<!DOCTYPE html>
<html  lang="zh">
<head>
    <meta charset="utf-8">
<title>Java并发学习之线程池ThreadPoolExecutor的小结 - 一灰灰Blog</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />



    <meta name="description" content="Java并发学习之线程池ThreadPoolExecutor的小结本篇博文将带着问题来回顾小结多线程池相关的知识点  线程池的几种创建方式 线程池的优点是什么 应用场景 如何使用 实现原理 异常状况怎么处理 线程池中任务的提交执行后，到线程执行，执行完成的整个流程逻辑 线程池中的线程回收机制">
<meta name="keywords" content="Java,并发">
<meta property="og:type" content="article">
<meta property="og:title" content="Java并发学习之线程池ThreadPoolExecutor的小结">
<meta property="og:url" content="https://blog.hhui.top/hexblog/2018/03/06/Java并发学习之线程池ThreadPoolExecutor的小结/index.html">
<meta property="og:site_name" content="一灰灰Blog">
<meta property="og:description" content="Java并发学习之线程池ThreadPoolExecutor的小结本篇博文将带着问题来回顾小结多线程池相关的知识点  线程池的几种创建方式 线程池的优点是什么 应用场景 如何使用 实现原理 异常状况怎么处理 线程池中任务的提交执行后，到线程执行，执行完成的整个流程逻辑 线程池中的线程回收机制">
<meta property="og:locale" content="zh-CN">
<meta property="og:image" content="https://blog.hhui.top/hexblog/images/og_image.png">
<meta property="og:updated_time" content="2018-07-25T14:55:41.000Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="Java并发学习之线程池ThreadPoolExecutor的小结">
<meta name="twitter:description" content="Java并发学习之线程池ThreadPoolExecutor的小结本篇博文将带着问题来回顾小结多线程池相关的知识点  线程池的几种创建方式 线程池的优点是什么 应用场景 如何使用 实现原理 异常状况怎么处理 线程池中任务的提交执行后，到线程执行，执行完成的整个流程逻辑 线程池中的线程回收机制">
<meta name="twitter:image" content="https://blog.hhui.top/hexblog/images/og_image.png">







<link rel="icon" href="/hexblog/images/avatar.jpg">


<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.7.2/css/bulma.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.4.1/css/all.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Ubuntu:400,600|Source+Code+Pro">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/highlight.js@9.12.0/styles/docco.css">


    
    
    
    <style>body>.footer,body>.navbar,body>.section{opacity:0}</style>
    

    
    
    
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/lightgallery@1.6.8/dist/css/lightgallery.min.css">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/justifiedGallery@3.7.0/dist/css/justifiedGallery.min.css">
    

    
    

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/outdatedbrowser@1.1.5/outdatedbrowser/outdatedbrowser.min.css">


    
    
    
    

<link rel="stylesheet" href="/hexblog/css/back-to-top.css">


    
    

    
    
<script>
var _hmt = _hmt || [];
(function() {
    var hm = document.createElement("script");
    hm.src = "//hm.baidu.com/hm.js?028d9e53f991d9739ecc7cc42e13c500";
    var s = document.getElementsByTagName("script")[0];
    s.parentNode.insertBefore(hm, s);
})();
</script>

    
    

    
    
<link rel="stylesheet" href="/hexblog/css/progressbar.css">
<script src="https://cdn.jsdelivr.net/npm/pace-js@1.0.2/pace.min.js"></script>

    
    
    

    
    
    


<link rel="stylesheet" href="/hexblog/css/style.css">
</head>
<body class="is-3-column">
    <nav class="navbar navbar-main">
    <div class="container">
        <div class="navbar-brand is-flex-center">
            <a class="navbar-item navbar-logo" href="/hexblog/">
            
                <img src="/hexblog/images/avatar.jpg" alt="Java并发学习之线程池ThreadPoolExecutor的小结" height="28">
            
            </a>
        </div>
        <div class="navbar-menu">
            
            <div class="navbar-start">
                
                <a class="navbar-item"
                href="/hexblog/.">首页</a>
                
                <a class="navbar-item"
                href="/hexblog/archives">归档</a>
                
                <a class="navbar-item"
                href="/hexblog/tags">标签</a>
                
                <a class="navbar-item"
                href="http://spring.hhui.top">Spring</a>
                
                <a class="navbar-item"
                href="/hexblog/categories/Java/">Java</a>
                
                <a class="navbar-item"
                href="/hexblog/categories/Python/">Python</a>
                
                <a class="navbar-item"
                href="/hexblog/categories/DB/">DB</a>
                
                <a class="navbar-item"
                href="/hexblog/categories/Shell/">Shell</a>
                
                <a class="navbar-item"
                href="/hexblog/categories/Quick系列/">Quick系列</a>
                
                <a class="navbar-item"
                href="/hexblog/categories/前端/">前端</a>
                
                <a class="navbar-item"
                href="/hexblog/categories/开源/">开源</a>
                
                <a class="navbar-item"
                href="/hexblog/categories/工具/">工具</a>
                
                <a class="navbar-item"
                href="/hexblog/categories/随笔/">随笔</a>
                
                <a class="navbar-item"
                href="/hexblog/about">关于</a>
                
            </div>
            
            <div class="navbar-end">
                
                    
                    
                    <a class="navbar-item" target="_blank" title="Download on GitHub" href="https://github.com/liuyueyi">
                        
                        <i class="fab fa-github"></i>
                        
                    </a>
                    
                
                
                
                <a class="navbar-item search" title="搜索" href="javascript:;">
                    <i class="fas fa-search"></i>
                </a>
                
            </div>
        </div>
    </div>
</nav>
    
    <section class="section">
        <div class="container">
            <div class="columns">
                <div class="column is-8-tablet is-8-desktop is-7-widescreen has-order-2 column-main"><div class="card">
    
        <span >
            <div class="thumbnail default_logo">
                <br/>
                <span >
                Java并发学习之线程池ThreadPoolExecutor的小结
                <br>
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                <span style="font-size:0.7em">by 一灰灰</span>
                </span>
            </div>
            </span>
    

    <div class="card-content article ">
        
        <div class="level article-meta is-size-7 is-uppercase is-mobile is-overflow-x-auto">
            <div class="level-left">
                <time class="level-item has-text-grey" datetime="2018-03-06T09:33:54.000Z">2018-03-06</time>
                
                <div class="level-item">
                <a class="has-link-black -link" href="/hexblog/categories/Java/">Java</a>&nbsp;/&nbsp;<a class="has-link-black -link" href="/hexblog/categories/Java/JDK/">JDK</a>&nbsp;/&nbsp;<a class="has-link-black -link" href="/hexblog/categories/Java/JDK/并发/">并发</a>
                </div>
                
                
                <span class="level-item has-text-grey" style='font-size: 1.2em;'>
                    
                    
                    1 小时 读完 (大约 7836 个字)
                </span>
                
                
                
                <span class="level-item has-text-grey" id="busuanzi_container_page_pv">
                    <i class="far fa-eye"></i>
                    <span id="busuanzi_value_page_pv">0</span>次访问
                </span>
                
            </div>
        </div>
        
        <h1 class="title is-size-3 is-size-4-mobile has-text-weight-normal">
            
                Java并发学习之线程池ThreadPoolExecutor的小结
            
        </h1>
        <div class="content">
            
                <!-- 文章详情页 -->
                <div id="toc" class="toc-article">
                <strong class="toc-title"> 文章目录 </strong>
                    <ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#Java并发学习之线程池ThreadPoolExecutor的小结"><span class="toc-text">Java并发学习之线程池ThreadPoolExecutor的小结</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#I-什么是线程池"><span class="toc-text">I. 什么是线程池</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#1-通俗讲解"><span class="toc-text">1. 通俗讲解</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2-线程池说明"><span class="toc-text">2. 线程池说明</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#3-线程池组成"><span class="toc-text">3. 线程池组成</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#II-线程池使用"><span class="toc-text">II. 线程池使用</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#1-构造参数详解"><span class="toc-text">1. 构造参数详解</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2-线程池的创建"><span class="toc-text">2. 线程池的创建</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#直接调用构造方法创建"><span class="toc-text">直接调用构造方法创建</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#利用-Executors创建"><span class="toc-text">利用 Executors创建</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#3-提交任务"><span class="toc-text">3. 提交任务</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#4-关闭线程池"><span class="toc-text">4. 关闭线程池</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#III-线程池实现原理"><span class="toc-text">III. 线程池实现原理</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#1-线程池状态"><span class="toc-text">1. 线程池状态</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2-任务提交逻辑"><span class="toc-text">2. 任务提交逻辑</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#3-任务执行"><span class="toc-text">3. 任务执行</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#execute-提交任务"><span class="toc-text">execute() - 提交任务</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#3-Worker类详解"><span class="toc-text">3. Worker类详解</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#IV-问题解答"><span class="toc-text">IV. 问题解答</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#1-如何创建线程池"><span class="toc-text">1. 如何创建线程池</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2-线程池的适用场景"><span class="toc-text">2. 线程池的适用场景</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#3-如何使用线程池"><span class="toc-text">3. 如何使用线程池</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#4-线程池实现原理-amp-任务提交后的流程"><span class="toc-text">4. 线程池实现原理 &amp; 任务提交后的流程</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#5-异常状况处理"><span class="toc-text">5. 异常状况处理</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#6-线程池关闭"><span class="toc-text">6. 线程池关闭</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#V-其他"><span class="toc-text">V. 其他</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#参考"><span class="toc-text">参考</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#个人博客：-Z-blog"><span class="toc-text">个人博客： Z+|blog</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#声明"><span class="toc-text">声明</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#扫描关注"><span class="toc-text">扫描关注</span></a></li></ol></li></ol></li></ol>
                </div>
            

            <h1 id="Java并发学习之线程池ThreadPoolExecutor的小结"><a href="#Java并发学习之线程池ThreadPoolExecutor的小结" class="headerlink" title="Java并发学习之线程池ThreadPoolExecutor的小结"></a>Java并发学习之线程池ThreadPoolExecutor的小结</h1><p>本篇博文将带着问题来回顾小结多线程池相关的知识点</p>
<ol>
<li>线程池的几种创建方式</li>
<li>线程池的优点是什么</li>
<li>应用场景</li>
<li>如何使用</li>
<li>实现原理</li>
<li>异常状况怎么处理</li>
<li>线程池中任务的提交执行后，到线程执行，执行完成的整个流程逻辑</li>
<li>线程池中的线程回收机制</li>
</ol>
<a id="more"></a>
<h2 id="I-什么是线程池"><a href="#I-什么是线程池" class="headerlink" title="I. 什么是线程池"></a>I. 什么是线程池</h2><h3 id="1-通俗讲解"><a href="#1-通俗讲解" class="headerlink" title="1. 通俗讲解"></a>1. 通俗讲解</h3><p>我们先举一个小例子来说一下什么是线程池，以及线程池的工作方式</p>
<p>首先在看一下线程池中提交一个任务的流程图</p>
<p><img src="https://s3.mogucdn.com/mlcdn/c45406/180306_1hd4i1726di8j655200j2e824f355_804x1176.png" alt="流程图"></p>
<p>下面就是实际的case：基本上大家都去过银行，我们就以到银行的柜台上办理业务的流程来说明线程池，我们先假设这里有一个xx银行（这里是广告位，待租😉），总共有8个柜台，平时只开放4个柜台，大厅内总共有20个座位。</p>
<ul>
<li>那么来一个办理业务的，如果开放的四个柜台上，有空的，直接上去办理业务即可</li>
<li>如果四个柜台都在处理业务了，那么办理业务则需要取一个号，到大厅的座位上等着叫号</li>
<li>如果大厅坐满了，银行经理决定开放所有的柜台，那么新来办理的人直接到新的柜台上处理</li>
<li>如果所有柜台都在处理，且大厅也满了，这个时候就告诉新来办理业务的现在已经满载了，你们到xxx地的银行去办理吧（或者回家等下午再来好了）</li>
</ul>
<p>从流程上的对比来看，就很相似了，虽然实际上银行可不会因为人的太多来新增开放柜台的数量，下面简单的将上面的case映射到线程池的成员上</p>
<ul>
<li>4个开放柜台 ： 对应线程池的corePoolSize(核心工作线程数)</li>
<li>8个总柜台：对应线程池的maximumPoolSize(最大工作线程数)</li>
<li>20个座位：对应线程池的workQueue(任务队列)</li>
</ul>
<p>所以线程池中提交一个任务时，优先看核心工作线程数是否已满，未满时，直接创建线程执行；已满，则丢入队列；如果队列也满了，则判断工作线程数是否超过最大数，没有则直接创建线程执行；否则直接“丢弃”这个任务了 （注意这个丢弃不是真的丢弃，其处理策略可以由你自己定义）</p>
<p>上面是基本流程，并没有涉及到工作线程的回收，线程池的状态（比如银行是否打烊了），任务的执行策略等</p>
<h3 id="2-线程池说明"><a href="#2-线程池说明" class="headerlink" title="2. 线程池说明"></a>2. 线程池说明</h3><p>线程池是一种多线程的处理机制，主要是为了减少线程的频繁创建和销毁，从而提升系统效率</p>
<p><strong>使用线程池优点</strong></p>
<ol>
<li>减少了创建和销毁线程的次数，每个工作线程都可以被重复利用，可执行多个任务</li>
<li>可以根据系统的承受能力，调整线程池中工作线线程的数量</li>
</ol>
<p><strong>使用线程池场景</strong></p>
<p>我们将线程进行拆分，创建线程耗时T1, 线程执行耗时T2, 销毁线程耗时T3</p>
<p>如果你的场景中，提交线程执行的任务非常频繁，且具体的执行耗时较短，即 T1 + T3 &gt; T2, 这种场景下使用线程池可以带来明显的性能提升</p>
<p>一般来说，如果不是你的任务只偶尔的运行几次，那么绝大部分场景都适合用线程池来处理</p>
<h3 id="3-线程池组成"><a href="#3-线程池组成" class="headerlink" title="3. 线程池组成"></a>3. 线程池组成</h3><p>类定义： <code>java.util.concurrent.ThreadPoolExecutor</code></p>
<p>构造</p>
<figure class="highlight java hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-comment">// 线程池构造方法</span></span><br><span class="line"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">ThreadPoolExecutor</span><span class="hljs-params">(<span class="hljs-keyword">int</span> corePoolSize, // 核心线程数</span></span></span><br><span class="line"><span class="hljs-function"><span class="hljs-params">                          <span class="hljs-keyword">int</span> maximumPoolSize, // 最大线程数</span></span></span><br><span class="line"><span class="hljs-function"><span class="hljs-params">                          <span class="hljs-keyword">long</span> keepAliveTime, // 存活时间</span></span></span><br><span class="line"><span class="hljs-function"><span class="hljs-params">                          TimeUnit unit,</span></span></span><br><span class="line"><span class="hljs-function"><span class="hljs-params">                          BlockingQueue&lt;Runnable&gt; workQueue, // 排队队列</span></span></span><br><span class="line"><span class="hljs-function"><span class="hljs-params">                          ThreadFactory threadFactory, // 创建线程的工作类</span></span></span><br><span class="line"><span class="hljs-function"><span class="hljs-params">                          RejectedExecutionHandler handler)</span> <span class="hljs-comment">// 线程数满，队列满时具体任务策略</span></span></span><br><span class="line"><span class="hljs-function"></span>&#123;</span><br><span class="line">    <span class="hljs-keyword">if</span> (corePoolSize &lt; <span class="hljs-number">0</span> ||</span><br><span class="line">        maximumPoolSize &lt;= <span class="hljs-number">0</span> ||</span><br><span class="line">        maximumPoolSize &lt; corePoolSize ||</span><br><span class="line">        keepAliveTime &lt; <span class="hljs-number">0</span>)</span><br><span class="line">        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalArgumentException();</span><br><span class="line">    <span class="hljs-keyword">if</span> (workQueue == <span class="hljs-keyword">null</span> || threadFactory == <span class="hljs-keyword">null</span> || handler == <span class="hljs-keyword">null</span>)</span><br><span class="line">        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> NullPointerException();</span><br><span class="line">    <span class="hljs-keyword">this</span>.corePoolSize = corePoolSize;</span><br><span class="line">    <span class="hljs-keyword">this</span>.maximumPoolSize = maximumPoolSize;</span><br><span class="line">    <span class="hljs-keyword">this</span>.workQueue = workQueue;</span><br><span class="line">    <span class="hljs-keyword">this</span>.keepAliveTime = unit.toNanos(keepAliveTime);</span><br><span class="line">    <span class="hljs-keyword">this</span>.threadFactory = threadFactory;</span><br><span class="line">    <span class="hljs-keyword">this</span>.handler = handler;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="II-线程池使用"><a href="#II-线程池使用" class="headerlink" title="II. 线程池使用"></a>II. 线程池使用</h2><h3 id="1-构造参数详解"><a href="#1-构造参数详解" class="headerlink" title="1. 构造参数详解"></a>1. 构造参数详解</h3><p>构造参数较多，创建一个线程池，当然首先得搞清楚这些参数是干嘛用的</p>
<table>
<thead>
<tr>
<th>参数</th>
<th>含义</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>corePoolSize</td>
<td>核心工作线程数</td>
<td>没有任务时，线程池中允许存在的最小空闲线程数 <br> <code>工作线程数 &lt; corePoolSize</code>时，提交任务创建工作线程来执行任务</td>
</tr>
<tr>
<td>maximumPoolSize</td>
<td>最大工作线程数</td>
<td>线程池中允许出现的最大工作线程数量 <br> 当<code>队列满 &amp;&amp; 工作线程数 &lt; maximumPoolSize</code>时，新的队列将创建线程来执行；<br> 如果<code>队列没有边界</code>，那么这个参数没有意义</td>
</tr>
<tr>
<td>workQueue</td>
<td>任务队列</td>
<td>保存待执行任务的阻塞队列；<br> 当 <code>(工作线程数 &gt;= corePoolSize) &amp;&amp; (任务数 &lt; 任务队列长度)</code>时，任务会offer()入队等待</td>
</tr>
<tr>
<td>keepAliveTime</td>
<td>工作线程最大空闲时间</td>
<td>当<code>线程数 &gt; corePoolSize</code>时，这个参数表示空闲线程存活时间； <br> 超时的空闲线程，会被回收掉，直到<code>线程数==corePoolSzie</code>; <br> 当<code>allowCoreThreadTimeOut=true</code>时，则超时的核心工作线程也会被回收</td>
</tr>
<tr>
<td>unit</td>
<td>时间单位</td>
<td>keepAliveTime的时间单位</td>
</tr>
<tr>
<td>threadFactory</td>
<td>线程创建工厂</td>
<td>创建线程的工厂类，可以在这里指定创建线程的name，设置守护线程，异常case处理等</td>
</tr>
<tr>
<td>handler</td>
<td>饱和策略执行器</td>
<td>线程池和队列都已满时，新提交任务的处理策略 <br> 默认是Abort(直抛Reject异常)，包括Discard(LIFO规则丢弃)、DiscardOldest(LRU规则丢弃) 以及 CallerRuns(调用者线程执行)，允许自定义执行器</td>
</tr>
</tbody>
</table>
<h3 id="2-线程池的创建"><a href="#2-线程池的创建" class="headerlink" title="2. 线程池的创建"></a>2. 线程池的创建</h3><h4 id="直接调用构造方法创建"><a href="#直接调用构造方法创建" class="headerlink" title="直接调用构造方法创建"></a>直接调用构造方法创建</h4><p>最直观的方式，直接构造方法new一个</p>
<figure class="highlight java hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-comment">// 报警线程池</span></span><br><span class="line">ExecutorService executorService = <span class="hljs-keyword">new</span> ThreadPoolExecutor(<span class="hljs-number">3</span>, <span class="hljs-number">5</span>, <span class="hljs-number">60</span>,</span><br><span class="line">    TimeUnit.SECONDS,</span><br><span class="line">    <span class="hljs-keyword">new</span> LinkedBlockingDeque&lt;Runnable&gt;(<span class="hljs-number">10</span>),</span><br><span class="line">    <span class="hljs-keyword">new</span> DefaultThreadFactory(<span class="hljs-string">"test-thread"</span>),</span><br><span class="line">    <span class="hljs-keyword">new</span> ThreadPoolExecutor.CallerRunsPolicy());</span><br><span class="line">    </span><br><span class="line">    </span><br><span class="line"><span class="hljs-comment">// 线程创建工厂，主要设置为非守护线程，指定线程名，设置优先级</span></span><br><span class="line"><span class="hljs-comment">// 关于这个工厂类，推荐看netty的实现</span></span><br><span class="line"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DefaultThreadFactory</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">ThreadFactory</span> </span>&#123;</span><br><span class="line">    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> AtomicInteger poolNumber = <span class="hljs-keyword">new</span> AtomicInteger(<span class="hljs-number">1</span>);</span><br><span class="line">    <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> ThreadGroup group;</span><br><span class="line">    <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> AtomicInteger threadNumber = <span class="hljs-keyword">new</span> AtomicInteger(<span class="hljs-number">1</span>);</span><br><span class="line">    <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> String namePrefix;</span><br><span class="line"></span><br><span class="line">    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">DefaultThreadFactory</span><span class="hljs-params">(String poolName)</span> </span>&#123;</span><br><span class="line">        <span class="hljs-keyword">if</span> (<span class="hljs-keyword">null</span> == poolName) &#123;</span><br><span class="line">            poolName = <span class="hljs-string">"pool"</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        SecurityManager s = System.getSecurityManager();</span><br><span class="line">        group = (s != <span class="hljs-keyword">null</span>) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();</span><br><span class="line">        namePrefix = poolName + poolNumber.getAndIncrement() + <span class="hljs-string">"-thread-"</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="hljs-meta">@Override</span></span><br><span class="line">    <span class="hljs-function"><span class="hljs-keyword">public</span> Thread <span class="hljs-title">newThread</span><span class="hljs-params">(Runnable r)</span> </span>&#123;</span><br><span class="line">        Thread t = <span class="hljs-keyword">new</span> Thread(group, r, namePrefix + threadNumber.getAndIncrement(), <span class="hljs-number">0</span>);</span><br><span class="line">        <span class="hljs-keyword">if</span> (t.isDaemon())</span><br><span class="line">            t.setDaemon(<span class="hljs-keyword">false</span>);</span><br><span class="line">        <span class="hljs-keyword">if</span> (t.getPriority() != Thread.NORM_PRIORITY)</span><br><span class="line">            t.setPriority(Thread.NORM_PRIORITY);</span><br><span class="line">        <span class="hljs-keyword">return</span> t;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h4 id="利用-Executors创建"><a href="#利用-Executors创建" class="headerlink" title="利用 Executors创建"></a>利用 Executors创建</h4><p>jdk1.5+ 中提供了 <code>java.util.concurrent.Executors</code> 来创建常见的集中线程池方式</p>
<p>关于各种线程池的说明可以参考: <a href="https://my.oschina.net/u/566591/blog/1591056" target="_blank" rel="noopener">Java并发学习之玩转线程池</a></p>
<p>固定大小线程池</p>
<figure class="highlight java hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-comment">// 创建一个固定大小的线程池</span></span><br><span class="line"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> ExecutorService <span class="hljs-title">newFixedThreadPool</span><span class="hljs-params">(<span class="hljs-keyword">int</span> nThreads)</span> </span>&#123;</span><br><span class="line">    <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> ThreadPoolExecutor(nThreads, nThreads,</span><br><span class="line">                                  <span class="hljs-number">0L</span>, TimeUnit.MILLISECONDS,</span><br><span class="line">                                  <span class="hljs-keyword">new</span> LinkedBlockingQueue&lt;Runnable&gt;());</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>工作窃取线程池</p>
<figure class="highlight java hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> ExecutorService <span class="hljs-title">newWorkStealingPool</span><span class="hljs-params">(<span class="hljs-keyword">int</span> parallelism)</span> </span>&#123;</span><br><span class="line">    <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> ForkJoinPool</span><br><span class="line">        (parallelism,</span><br><span class="line">         ForkJoinPool.defaultForkJoinWorkerThreadFactory,</span><br><span class="line">         <span class="hljs-keyword">null</span>, <span class="hljs-keyword">true</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>创建单线程池</p>
<figure class="highlight java hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> ExecutorService <span class="hljs-title">newSingleThreadExecutor</span><span class="hljs-params">()</span> </span>&#123;</span><br><span class="line">    <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> FinalizableDelegatedExecutorService</span><br><span class="line">        (<span class="hljs-keyword">new</span> ThreadPoolExecutor(<span class="hljs-number">1</span>, <span class="hljs-number">1</span>,</span><br><span class="line">                                <span class="hljs-number">0L</span>, TimeUnit.MILLISECONDS,</span><br><span class="line">                                <span class="hljs-keyword">new</span> LinkedBlockingQueue&lt;Runnable&gt;()));</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>缓存线程池</p>
<figure class="highlight java hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> ExecutorService <span class="hljs-title">newCachedThreadPool</span><span class="hljs-params">()</span> </span>&#123;</span><br><span class="line">    <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> ThreadPoolExecutor(<span class="hljs-number">0</span>, Integer.MAX_VALUE,</span><br><span class="line">                                  <span class="hljs-number">60L</span>, TimeUnit.SECONDS,</span><br><span class="line">                                  <span class="hljs-keyword">new</span> SynchronousQueue&lt;Runnable&gt;());</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>定时任务线程池</p>
<figure class="highlight plain hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) &#123;</span><br><span class="line">    return new ScheduledThreadPoolExecutor(corePoolSize);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>不可配置线程池</p>
<figure class="highlight plain hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">public static ExecutorService unconfigurableExecutorService(ExecutorService executor) &#123;</span><br><span class="line">    if (executor == null)</span><br><span class="line">        throw new NullPointerException();</span><br><span class="line">    return new DelegatedExecutorService(executor);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="3-提交任务"><a href="#3-提交任务" class="headerlink" title="3. 提交任务"></a>3. 提交任务</h3><p>execute: 提交无须返回值的任务</p>
<p>submit(Runnable): 适用于提交需要返回值的任务</p>
<ul>
<li>相比较于上面的，区别是这个会返回一个 Future<v> 对象，通过调用future.get()可以获取线程的返回值，</v></li>
<li>其中这个方程是线程阻塞的，直到返回了结果之后，才会继续执行下去</li>
</ul>
<h3 id="4-关闭线程池"><a href="#4-关闭线程池" class="headerlink" title="4. 关闭线程池"></a>4. 关闭线程池</h3><p>shutdown(): 有序地关闭线程池，已提交的任务会被执行(包含正在执行和任务队列中的)，但会拒绝新任务</p>
<p>shutdownNow(): 立即(尝试)停止执行所有任务(包含正在执行和任务队列中的)，并返回待执行任务列表</p>
<h2 id="III-线程池实现原理"><a href="#III-线程池实现原理" class="headerlink" title="III. 线程池实现原理"></a>III. 线程池实现原理</h2><h3 id="1-线程池状态"><a href="#1-线程池状态" class="headerlink" title="1. 线程池状态"></a>1. 线程池状态</h3><p>线程池状态流程如下：</p>
<p>RUNNING -&gt; SHUTDOWN -&gt; STOP -&gt; TIDYING -&gt; TERMINATED</p>
<p>每个状态含义</p>
<figure class="highlight java hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-comment">//高3位111，低29位为0 该状态下线程池会接收新提交任务和执行队列任务</span></span><br><span class="line"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> RUNNING    = -<span class="hljs-number">1</span> &lt;&lt; COUNT_BITS;</span><br><span class="line"></span><br><span class="line"><span class="hljs-comment">//高3位000，低29位为0 该状态下线程池不再接收新任务，但还会继续执行队列任务</span></span><br><span class="line"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> SHUTDOWN   =  <span class="hljs-number">0</span> &lt;&lt; COUNT_BITS;</span><br><span class="line"></span><br><span class="line"><span class="hljs-comment">//高3位001，低29位为0 该状态下线程池不再接收新任务，不会再执行队列任务，并会中断正在执行中的任务</span></span><br><span class="line"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> STOP       =  <span class="hljs-number">1</span> &lt;&lt; COUNT_BITS;</span><br><span class="line"></span><br><span class="line"><span class="hljs-comment">//高3位010，低29位为0 该状态下线程池的所有任务都被终止，工作线程数为0，期间会调用钩子方法terminated()</span></span><br><span class="line"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> TIDYING    =  <span class="hljs-number">2</span> &lt;&lt; COUNT_BITS;</span><br><span class="line"></span><br><span class="line"><span class="hljs-comment">//高3位011，低29位为0 该状态下表明线程池terminated()方法已经调用完成</span></span><br><span class="line"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> TERMINATED =  <span class="hljs-number">3</span> &lt;&lt; COUNT_BITS;</span><br></pre></td></tr></table></figure>
<h3 id="2-任务提交逻辑"><a href="#2-任务提交逻辑" class="headerlink" title="2. 任务提交逻辑"></a>2. 任务提交逻辑</h3><p>最开始的流图就说明了任务提交后的流程，针对流程块也就不继续细说，只提一个注意点</p>
<ol>
<li><p>若实际工作线程数workers&lt;核心工作线程数corePoolSize，则创建新工作线程来执行新任务execute(Runable)</p>
</li>
<li><p>若实际工作线程数workers&gt;=核心工作线程数corePoolSize(核心工作线程们都在执行任务)且任务队列workQueue未满，则将任务加入到任务队列workQueue中</p>
</li>
<li><p>若任务队列workQueue已满，则创建新工作线程来执行任务execute()</p>
</li>
<li><p>若实际工作线程数workers&gt;=最大工作线程数maximumPoolSize(所有线程都在执行任务)，此时任务数已饱和，需要根据饱和拒绝策略rejectedExecutionHandler执行相对应的饱和拒绝操作</p>
</li>
</ol>
<p>线程池的总体设计是基于性能考虑，尽可能避免获取全局锁：</p>
<ol>
<li><p>由于创建新线程时都需要获取全局锁，因此步骤1和步骤3必须加锁</p>
</li>
<li><p>为了避免多次获取全局锁(性能伸缩瓶颈)，当实际工作线程数&gt;=核心工作线程数时，之后会执行步骤2(入队时无须获取全局锁)</p>
</li>
</ol>
<p>线程池内线程回收策略</p>
<ol>
<li><p>若实际工作线程数workers&gt;核心工作线程数corePoolSize，回收空闲时间超过keepAliveTime的空闲的非核心线程(减少工作线程数直到&lt;=核心工作线程数即可)</p>
</li>
<li><p>若设置allowCoreThreadTimeOut为true时，则超过keepAliveTime的空闲的核心工作线程也会被回收</p>
</li>
</ol>
<h3 id="3-任务执行"><a href="#3-任务执行" class="headerlink" title="3. 任务执行"></a>3. 任务执行</h3><p>说明，下面两段代码解析来自转载： <a href="https://juejin.im/entry/5a80065f5188257a7f1da4c1?utm_source=gold_browser_extension" target="_blank" rel="noopener">并发番@ThreadPoolExecutor</a></p>
<h4 id="execute-提交任务"><a href="#execute-提交任务" class="headerlink" title="execute() - 提交任务"></a>execute() - 提交任务</h4><figure class="highlight java hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-comment">/**</span></span><br><span class="line"><span class="hljs-comment"> * 1.若实际工作线程数 &lt; 核心工作线程数，会尝试创建一个工作线程去执行该</span></span><br><span class="line"><span class="hljs-comment"> * 任务，即该command会作为该线程的第一个任务，即第一个firstTask</span></span><br><span class="line"><span class="hljs-comment"> * </span></span><br><span class="line"><span class="hljs-comment"> * 2.若任务入队成功，仍需要执行双重校验，原因有两点：</span></span><br><span class="line"><span class="hljs-comment"> *      - 第一个是去确认是否需要新建一个工作线程，因为可能存在</span></span><br><span class="line"><span class="hljs-comment"> *        在上次检查后已经死亡died的工作线程</span></span><br><span class="line"><span class="hljs-comment"> *      - 第二个是可能在进入该方法后线程池被关闭了，</span></span><br><span class="line"><span class="hljs-comment"> *        比如执行shutdown()</span></span><br><span class="line"><span class="hljs-comment"> *   因此需要再次检查state状态，并分别处理以上两种情况：</span></span><br><span class="line"><span class="hljs-comment"> *      - 若线程池中已无可用工作线程了，则需要新建一个工作线程 </span></span><br><span class="line"><span class="hljs-comment"> *      - 若线程池已被关闭，则需要回滚入队列(若有必要)</span></span><br><span class="line"><span class="hljs-comment"> * </span></span><br><span class="line"><span class="hljs-comment"> * 3.若任务入队失败(比如队列已满)，则需要新建一个工作线程； </span></span><br><span class="line"><span class="hljs-comment"> *      - 若新建线程失败，说明线程池已停止或者已饱和，必须执行拒绝策略</span></span><br><span class="line"><span class="hljs-comment"> */</span></span><br><span class="line"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">execute</span><span class="hljs-params">(Runnable command)</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="hljs-comment">//新任务不允许为空，空则抛出NPE</span></span><br><span class="line">    <span class="hljs-keyword">if</span> (command == <span class="hljs-keyword">null</span>)</span><br><span class="line">        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> NullPointerException();</span><br><span class="line"></span><br><span class="line">    <span class="hljs-comment">// ctl 为线程池状态控制器，用于保证线程池状态和工作线程数 </span></span><br><span class="line">    <span class="hljs-comment">// 低29位为工作线程数量，高3位为线程池状态</span></span><br><span class="line">    <span class="hljs-keyword">int</span> c = ctl.get();</span><br><span class="line"></span><br><span class="line">    <span class="hljs-comment">/**</span></span><br><span class="line"><span class="hljs-comment">     * case1：当实际工作线程数 &lt; 核心工作线程数时</span></span><br><span class="line"><span class="hljs-comment">     * 执行方案：会创建一个新的工作线程去执行该任务</span></span><br><span class="line"><span class="hljs-comment">     * 注意：此时即使有其他空闲的工作线程也还是会新增工作线程，</span></span><br><span class="line"><span class="hljs-comment">     *      直到达到核心工作线程数为止</span></span><br><span class="line"><span class="hljs-comment">     */</span></span><br><span class="line">    <span class="hljs-keyword">if</span> (workerCountOf(c) &lt; corePoolSize) &#123;</span><br><span class="line"></span><br><span class="line">        <span class="hljs-comment">/**</span></span><br><span class="line"><span class="hljs-comment">         * 新增工作线程，true表示要对比的是核心工作线程数</span></span><br><span class="line"><span class="hljs-comment">         * 一旦新增成功就开始执行当前任务</span></span><br><span class="line"><span class="hljs-comment">         * 期间也会通过自旋获取队列任务进行执行</span></span><br><span class="line"><span class="hljs-comment">         */</span></span><br><span class="line">        <span class="hljs-keyword">if</span> (addWorker(command, <span class="hljs-keyword">true</span>))</span><br><span class="line">            <span class="hljs-keyword">return</span>;</span><br><span class="line"></span><br><span class="line">        <span class="hljs-comment">/**</span></span><br><span class="line"><span class="hljs-comment">         * 需要重新获取控制器状态，说明新增线程失败</span></span><br><span class="line"><span class="hljs-comment">         * 线程失败的原因可能有两种：</span></span><br><span class="line"><span class="hljs-comment">         *  - 1.线程池已被关闭，非RUNNING状态的线程池是不允许接收新任务的</span></span><br><span class="line"><span class="hljs-comment">         *  - 2.并发时，假如都通过了workerCountOf(c) &lt; corePoolSize校验，但其他线程</span></span><br><span class="line"><span class="hljs-comment">         *      可能会在addWorker前先创建出线程，导致workerCountOf(c) &gt;= corePoolSize，</span></span><br><span class="line"><span class="hljs-comment">         *      即实际工作线程数 &gt;= 核心工作线程数，此时需要进入case2</span></span><br><span class="line"><span class="hljs-comment">         */</span></span><br><span class="line">        c = ctl.get();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="hljs-comment">/**</span></span><br><span class="line"><span class="hljs-comment">     * case2：当实际工作线程数&gt;=核心线程数时，新提交任务需要入队</span></span><br><span class="line"><span class="hljs-comment">     * 执行方案：一旦入队成功，仍需要处理线程池状态突变和工作线程死亡的情况</span></span><br><span class="line"><span class="hljs-comment">     */</span></span><br><span class="line">    <span class="hljs-keyword">if</span> (isRunning(c) &amp;&amp; workQueue.offer(command)) &#123;</span><br><span class="line"></span><br><span class="line">        <span class="hljs-comment">//双重校验</span></span><br><span class="line">        <span class="hljs-keyword">int</span> recheck = ctl.get();</span><br><span class="line"></span><br><span class="line">        <span class="hljs-comment">/**</span></span><br><span class="line"><span class="hljs-comment">         * recheck的目的是为了防止线程池状态的突变 - 即被关闭</span></span><br><span class="line"><span class="hljs-comment">         * 一旦线程池非RUNNING状态时，除了从队列中移除该任务(回滚)外</span></span><br><span class="line"><span class="hljs-comment">         * 还需要执行任务拒绝策略处理新提交的任务</span></span><br><span class="line"><span class="hljs-comment">         */</span></span><br><span class="line">        <span class="hljs-keyword">if</span> (!isRunning(recheck) &amp;&amp; remove(command))</span><br><span class="line">            <span class="hljs-comment">//执行任务拒绝策略</span></span><br><span class="line">            reject(command);</span><br><span class="line"></span><br><span class="line">        <span class="hljs-comment">/**</span></span><br><span class="line"><span class="hljs-comment">         * 若线程池还是RUNNING状态 或 </span></span><br><span class="line"><span class="hljs-comment">         *  队列移除失败(可能正好被一个工作线程拿到处理了)</span></span><br><span class="line"><span class="hljs-comment">         * 此时需要确保至少有一个工作线程还可以干活</span></span><br><span class="line"><span class="hljs-comment">         * 补充一句：之所有无须与核心工作线程数或最大线程数相比，而只是比较0的原因是</span></span><br><span class="line"><span class="hljs-comment">         *          只要保证有一个工作线程可以干活就行，它会自动去获取任务</span></span><br><span class="line"><span class="hljs-comment">         */</span></span><br><span class="line">        <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (workerCountOf(recheck) == <span class="hljs-number">0</span>)</span><br><span class="line">            <span class="hljs-comment">/**</span></span><br><span class="line"><span class="hljs-comment">             * 若工作线程都已死亡，需要新增一个工作线程去干活</span></span><br><span class="line"><span class="hljs-comment">             * 死亡原因可能是线程超时或者异常等等复杂情况</span></span><br><span class="line"><span class="hljs-comment">             *</span></span><br><span class="line"><span class="hljs-comment">             * 第一个参数为null指的是传入一个空任务，</span></span><br><span class="line"><span class="hljs-comment">             * 目的是创建一个新工作线程去处理队列中的剩余任务</span></span><br><span class="line"><span class="hljs-comment">             * 第二个参数为false目的是提示可以扩容到最大工作线程数</span></span><br><span class="line"><span class="hljs-comment">             */</span></span><br><span class="line">            addWorker(<span class="hljs-keyword">null</span>, <span class="hljs-keyword">false</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="hljs-comment">/**</span></span><br><span class="line"><span class="hljs-comment">     * case3：一旦线程池被关闭 或者 新任务入队失败(队列已满)</span></span><br><span class="line"><span class="hljs-comment">     * 执行方案：会尝试创建一个新的工作线程，并允许扩容到最大工作线程数</span></span><br><span class="line"><span class="hljs-comment">     * 注意：一旦创建失败，比如超过最大工作线程数，需要执行任务拒绝策略</span></span><br><span class="line"><span class="hljs-comment">     */</span></span><br><span class="line">    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (!addWorker(command, <span class="hljs-keyword">false</span>))</span><br><span class="line">        <span class="hljs-comment">//执行任务拒绝策略</span></span><br><span class="line">        reject(command);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>上面的代码虽然非常少，但是逻辑还是比较多的，创建线程是根据 <code>addWorker</code>方法来实现的，其主要逻辑为</p>
<figure class="highlight java hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-comment">/**</span></span><br><span class="line"><span class="hljs-comment"> * 新增工作线程需要遵守线程池控制状态规定和边界限制</span></span><br><span class="line"><span class="hljs-comment"> *</span></span><br><span class="line"><span class="hljs-comment"> * <span class="hljs-doctag">@param</span> core core为true时允许扩容到核心工作线程数，否则为最大工作线程数</span></span><br><span class="line"><span class="hljs-comment"> * <span class="hljs-doctag">@return</span> 新增成功返回true，失败返回false</span></span><br><span class="line"><span class="hljs-comment"> */</span></span><br><span class="line"><span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">addWorker</span><span class="hljs-params">(Runnable firstTask, <span class="hljs-keyword">boolean</span> core)</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="hljs-comment">//重试标签</span></span><br><span class="line">    retry:</span><br><span class="line"></span><br><span class="line">    <span class="hljs-comment">/***</span></span><br><span class="line"><span class="hljs-comment">     * 外部自旋 -&gt; 目的是确认是否能够新增工作线程</span></span><br><span class="line"><span class="hljs-comment">     * 允许新增线程的条件有两个：</span></span><br><span class="line"><span class="hljs-comment">     *   1.满足线程池状态条件 -&gt; 条件一</span></span><br><span class="line"><span class="hljs-comment">     *   2.实际工作线程满足数量边界条件 -&gt; 条件二</span></span><br><span class="line"><span class="hljs-comment">     * 不满足条件时会直接返回false，表示新增工作线程失败</span></span><br><span class="line"><span class="hljs-comment">     */</span></span><br><span class="line">    <span class="hljs-keyword">for</span> (;;) &#123;</span><br><span class="line"></span><br><span class="line">        <span class="hljs-comment">//读取原子控制量 - 包含workerCount(实际工作线程数)和runState(线程池状态)</span></span><br><span class="line">        <span class="hljs-keyword">int</span> c = ctl.get();</span><br><span class="line"></span><br><span class="line">        <span class="hljs-comment">//读取线程池状态</span></span><br><span class="line">        <span class="hljs-keyword">int</span> rs = runStateOf(c);</span><br><span class="line"></span><br><span class="line">        <span class="hljs-comment">/**</span></span><br><span class="line"><span class="hljs-comment">         * 条件一.判断是否满足线程池状态条件</span></span><br><span class="line"><span class="hljs-comment">         *  1.只有两种情况允许新增线程：</span></span><br><span class="line"><span class="hljs-comment">         *    1.1 线程池状态==RUNNING</span></span><br><span class="line"><span class="hljs-comment">         *    1.2 线程池状态==SHUTDOWN且firstTask为null同时队列非空</span></span><br><span class="line"><span class="hljs-comment">         *</span></span><br><span class="line"><span class="hljs-comment">         *  2.线程池状态&gt;=SHUTDOWN时不允许接收新任务，具体如下：</span></span><br><span class="line"><span class="hljs-comment">         *    2.1 线程池状态&gt;SHUTDOWN，即为STOP、TIDYING、TERMINATED</span></span><br><span class="line"><span class="hljs-comment">         *    2.2 线程池状态==SHUTDOWN，但firstTask非空</span></span><br><span class="line"><span class="hljs-comment">         *    2.3 线程池状态==SHUTDOWN且firstTask为空，但队列为空</span></span><br><span class="line"><span class="hljs-comment">         *  补充：针对1.2、2.2、2.3的情况具体请参加后面的"小问答"环节</span></span><br><span class="line"><span class="hljs-comment">         */</span></span><br><span class="line">        <span class="hljs-keyword">if</span> (rs &gt;= SHUTDOWN &amp;&amp;</span><br><span class="line">            !(rs == SHUTDOWN &amp;&amp; firstTask == <span class="hljs-keyword">null</span> &amp;&amp; ! workQueue.isEmpty()))</span><br><span class="line">            <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;</span><br><span class="line"></span><br><span class="line">        <span class="hljs-comment">/***</span></span><br><span class="line"><span class="hljs-comment">         * 内部自旋 -&gt; 条件二.判断实际工作线程数是否满足数量边界条件</span></span><br><span class="line"><span class="hljs-comment">         *   -数量边界条件满足会对尝试workerCount实现CAS自增，否则新增失败</span></span><br><span class="line"><span class="hljs-comment">         *   -当CAS失败时会再次重新判断是否满足新增条件：</span></span><br><span class="line"><span class="hljs-comment">         *       1.若此期间线程池状态突变(被关闭)，重新判断线程池状态条件和数量边界条件</span></span><br><span class="line"><span class="hljs-comment">        *        2.若此期间线程池状态一致，则只需重新判断数量边界条件</span></span><br><span class="line"><span class="hljs-comment">        */</span></span><br><span class="line">        <span class="hljs-keyword">for</span> (;;) &#123;</span><br><span class="line"></span><br><span class="line">            <span class="hljs-comment">//读取实际工作线程数</span></span><br><span class="line">            <span class="hljs-keyword">int</span> wc = workerCountOf(c);</span><br><span class="line"></span><br><span class="line">            <span class="hljs-comment">/**</span></span><br><span class="line"><span class="hljs-comment">             * 新增工作线程会因两种实际工作线程数超标情况而失败：</span></span><br><span class="line"><span class="hljs-comment">             *  1.实际工作线程数 &gt;= 最大容量</span></span><br><span class="line"><span class="hljs-comment">             *  2.实际工作线程数 &gt; 工作线程比较边界数(当前最大扩容数)</span></span><br><span class="line"><span class="hljs-comment">             *   -若core = true，比较边界数 = 核心工作线程数</span></span><br><span class="line"><span class="hljs-comment">             *   -若core = false，比较边界数 = 最大工作线程数</span></span><br><span class="line"><span class="hljs-comment">             */</span></span><br><span class="line">            <span class="hljs-keyword">if</span> (wc &gt;= CAPACITY || wc &gt;= (core ? corePoolSize : maximumPoolSize))</span><br><span class="line">                <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;</span><br><span class="line"></span><br><span class="line">            <span class="hljs-comment">/**</span></span><br><span class="line"><span class="hljs-comment">             * 实际工作线程计数CAS自增:</span></span><br><span class="line"><span class="hljs-comment">             *   1.一旦成功直接退出整个retry循环，表明新增条件都满足</span></span><br><span class="line"><span class="hljs-comment">             *   2.因并发竞争导致CAS更新失败的原因有三种: </span></span><br><span class="line"><span class="hljs-comment">             *      2.1 线程池刚好已新增一个工作线程</span></span><br><span class="line"><span class="hljs-comment">             *        -&gt; 计数增加，只需重新判断数量边界条件</span></span><br><span class="line"><span class="hljs-comment">             *      2.2 刚好其他工作线程运行期发生错误或因超时被回收</span></span><br><span class="line"><span class="hljs-comment">             *        -&gt; 计数减少，只需重新判断数量边界条件</span></span><br><span class="line"><span class="hljs-comment">             *      2.3 刚好线程池被关闭 </span></span><br><span class="line"><span class="hljs-comment">             *        -&gt; 计数减少，工作线程被回收，</span></span><br><span class="line"><span class="hljs-comment">             *           需重新判断线程池状态条件和数量边界条件</span></span><br><span class="line"><span class="hljs-comment">             */</span></span><br><span class="line">            <span class="hljs-keyword">if</span> (compareAndIncrementWorkerCount(c))</span><br><span class="line">                <span class="hljs-keyword">break</span> retry;</span><br><span class="line"></span><br><span class="line">            <span class="hljs-comment">//重新读取原子控制量 -&gt; 原因是在此期间可能线程池被关闭了</span></span><br><span class="line">            c = ctl.get();</span><br><span class="line"></span><br><span class="line">            <span class="hljs-comment">/**</span></span><br><span class="line"><span class="hljs-comment">             * 快速检测是否发生线程池状态突变</span></span><br><span class="line"><span class="hljs-comment">             *  1.若状态突变，重新判断线程池状态条件和数量边界条件</span></span><br><span class="line"><span class="hljs-comment">             *  2.若状态一致，则只需重新判断数量边界条件</span></span><br><span class="line"><span class="hljs-comment">             */</span></span><br><span class="line">            <span class="hljs-keyword">if</span> (runStateOf(c) != rs)</span><br><span class="line">                <span class="hljs-keyword">continue</span> retry;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="hljs-comment">/**</span></span><br><span class="line"><span class="hljs-comment">     * 这里是addWorker方法的一个分割线</span></span><br><span class="line"><span class="hljs-comment">     * 前面的代码的作用是决定了线程池接受还是拒绝新增工作线程</span></span><br><span class="line"><span class="hljs-comment">     * 后面的代码的作用是真正开始新增工作线程并封装成Worker接着执行后续操作</span></span><br><span class="line"><span class="hljs-comment">     * PS:虽然笔者觉得这个方法其实可以拆分成两个方法的(在break retry的位置)</span></span><br><span class="line"><span class="hljs-comment">     */</span></span><br><span class="line"></span><br><span class="line">    <span class="hljs-comment">//记录新增的工作线程是否开始工作</span></span><br><span class="line">    <span class="hljs-keyword">boolean</span> workerStarted = <span class="hljs-keyword">false</span>;</span><br><span class="line"></span><br><span class="line">    <span class="hljs-comment">//记录新增的worker是否成功添加到workers集合中</span></span><br><span class="line">    <span class="hljs-keyword">boolean</span> workerAdded = <span class="hljs-keyword">false</span>;</span><br><span class="line"></span><br><span class="line">    Worker w = <span class="hljs-keyword">null</span>;</span><br><span class="line">    <span class="hljs-keyword">try</span> &#123;</span><br><span class="line"></span><br><span class="line">        <span class="hljs-comment">//将新提交的任务和当前线程封装成一个Worker</span></span><br><span class="line">        w = <span class="hljs-keyword">new</span> Worker(firstTask);</span><br><span class="line"></span><br><span class="line">        <span class="hljs-comment">//获取新创建的实际工作线程</span></span><br><span class="line">        <span class="hljs-keyword">final</span> Thread t = w.thread;</span><br><span class="line"></span><br><span class="line">        <span class="hljs-comment">/**</span></span><br><span class="line"><span class="hljs-comment">         * 检测是否有可执行任务的线程，即是否成功创建了新的工作线程</span></span><br><span class="line"><span class="hljs-comment">         *   1.若存在，则选择执行任务</span></span><br><span class="line"><span class="hljs-comment">         *   2.若不存在，则需要执行addWorkerFailed()方法</span></span><br><span class="line"><span class="hljs-comment">         */</span></span><br><span class="line">        <span class="hljs-keyword">if</span> (t != <span class="hljs-keyword">null</span>) &#123;</span><br><span class="line"></span><br><span class="line">            <span class="hljs-comment">/**</span></span><br><span class="line"><span class="hljs-comment">             * 新增工作线程需要加全局锁</span></span><br><span class="line"><span class="hljs-comment">             * 目的是为了确保安全更新workers集合和largestPoolSize</span></span><br><span class="line"><span class="hljs-comment">             */</span></span><br><span class="line">            <span class="hljs-keyword">final</span> ReentrantLock mainLock = <span class="hljs-keyword">this</span>.mainLock;</span><br><span class="line"></span><br><span class="line">            mainLock.lock();</span><br><span class="line">            <span class="hljs-keyword">try</span> &#123;</span><br><span class="line"></span><br><span class="line">                <span class="hljs-comment">/**</span></span><br><span class="line"><span class="hljs-comment">                 * 获得全局锁后，需再次检测当前线程池状态</span></span><br><span class="line"><span class="hljs-comment">                 * 原因在于预防两种非法情况：</span></span><br><span class="line"><span class="hljs-comment">                 *  1.线程工厂创建线程失败</span></span><br><span class="line"><span class="hljs-comment">                 *  2.在锁被获取之前，线程池就被关闭了</span></span><br><span class="line"><span class="hljs-comment">                 */</span></span><br><span class="line">                <span class="hljs-keyword">int</span> rs = runStateOf(ctl.get());</span><br><span class="line"></span><br><span class="line">                <span class="hljs-comment">/**</span></span><br><span class="line"><span class="hljs-comment">                 * 只有两种情况是允许添加work进入works集合的</span></span><br><span class="line"><span class="hljs-comment">                 * 也只有进入workers集合后才是真正的工作线程，并开始执行任务</span></span><br><span class="line"><span class="hljs-comment">                 *  1.线程池状态为RUNNING(即rs&lt;SHUTDOWN)</span></span><br><span class="line"><span class="hljs-comment">                 *  2.线程池状态为SHUTDOWN且传入一个空任务</span></span><br><span class="line"><span class="hljs-comment">                 *  (理由参见：小问答之快速检测线程池状态?) </span></span><br><span class="line"><span class="hljs-comment">                 */</span></span><br><span class="line">                <span class="hljs-keyword">if</span> (rs &lt; SHUTDOWN ||</span><br><span class="line">                    (rs == SHUTDOWN &amp;&amp; firstTask == <span class="hljs-keyword">null</span>)) &#123;</span><br><span class="line"></span><br><span class="line">                    <span class="hljs-comment">/**</span></span><br><span class="line"><span class="hljs-comment">                     * 若线程处于活动状态时，说明线程已启动，需要立即抛出"线程状态非法异常"</span></span><br><span class="line"><span class="hljs-comment">                     * 原因是线程是在后面才被start的，已被start的不允许再被添加到workers集合中</span></span><br><span class="line"><span class="hljs-comment">                     * 换句话说该方法新增线程时，而线程是新的，本身应该是初始状态(new)</span></span><br><span class="line"><span class="hljs-comment">                     * 可能出现的场景：自定义线程工厂newThread有可能会提前启动线程</span></span><br><span class="line"><span class="hljs-comment">                     */</span></span><br><span class="line">                    <span class="hljs-keyword">if</span> (t.isAlive())</span><br><span class="line">                        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalThreadStateException();</span><br><span class="line"></span><br><span class="line">                    <span class="hljs-comment">//由于加锁，所以可以放心的加入集合</span></span><br><span class="line">                    workers.add(w);</span><br><span class="line">                    <span class="hljs-keyword">int</span> s = workers.size();</span><br><span class="line"></span><br><span class="line">                    <span class="hljs-comment">//更新最大工作线程数，由于持有锁，所以无需CAS</span></span><br><span class="line">                    <span class="hljs-keyword">if</span> (s &gt; largestPoolSize)</span><br><span class="line">                        largestPoolSize = s;</span><br><span class="line"></span><br><span class="line">                    <span class="hljs-comment">//确认新建的worker已被添加到workers集合中  </span></span><br><span class="line">                    workerAdded = <span class="hljs-keyword">true</span>;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125; <span class="hljs-keyword">finally</span> &#123;</span><br><span class="line"></span><br><span class="line">                <span class="hljs-comment">//千万不要忘记主动解锁</span></span><br><span class="line">                mainLock.unlock();</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            <span class="hljs-comment">/**</span></span><br><span class="line"><span class="hljs-comment">             * 一旦新建工作线程被加入工作线程集合中，就意味着其可以开始干活了</span></span><br><span class="line"><span class="hljs-comment">             * 有心的您肯定发现在线程start之前已经释放锁了</span></span><br><span class="line"><span class="hljs-comment">             * 原因在于一旦workerAdded为true时，说明锁的目的已经达到</span></span><br><span class="line"><span class="hljs-comment">             * 根据最小化锁作用域的原则，线程执行任务无须加锁，这是种优化</span></span><br><span class="line"><span class="hljs-comment">             * 也希望您在使用锁时尽量保证锁的作用域最小化</span></span><br><span class="line"><span class="hljs-comment">             */</span></span><br><span class="line">            <span class="hljs-keyword">if</span> (workerAdded) &#123;</span><br><span class="line"></span><br><span class="line">                <span class="hljs-comment">/**</span></span><br><span class="line"><span class="hljs-comment">                 * 启动线程，开始干活啦</span></span><br><span class="line"><span class="hljs-comment">                 * 若您看过笔者的"并发番<span class="hljs-doctag">@Thread</span>一文通"肯定知道start()后，</span></span><br><span class="line"><span class="hljs-comment">                 * 一旦线程初始化完成便会立即调用run()方法</span></span><br><span class="line"><span class="hljs-comment">                 */</span></span><br><span class="line">                t.start();</span><br><span class="line"></span><br><span class="line">                <span class="hljs-comment">//确认该工作线程开始干活了</span></span><br><span class="line">                workerStarted = <span class="hljs-keyword">true</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125; <span class="hljs-keyword">finally</span> &#123;</span><br><span class="line"></span><br><span class="line">        <span class="hljs-comment">//若新建工作线程失败或新建工作线程后没有成功执行，需要做新增失败处理</span></span><br><span class="line">        <span class="hljs-keyword">if</span> (!workerStarted)</span><br><span class="line">            addWorkerFailed(w);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="hljs-comment">//返回结果表明新建的工作线程是否已启动执行</span></span><br><span class="line">    <span class="hljs-keyword">return</span> workerStarted;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>小问：快速检测线程状态时，情况1.2、2.1、2.3的意义是什么？</strong></p>
<p>小答：在阐明这个问题之前，我们先明确两个知识点：</p>
<ol>
<li><p>新增Worker的目的是处理任务，任务来源分初始任务和队列任务(即剩余的待处理任务)</p>
</li>
<li><p>线程池在非RUNNING状态下是不允许接收新任务的，换句话说您都要下班了，难道还想接新需求？</p>
</li>
</ol>
<p>针对2.1 - &gt; 线程池状态==SHUTDOWN，但firstTask！= null，不允许新增Worker<br>当线程池状态为SHUTDOWN时，由于不允许接收新任务，因此一旦firstTask！= null需要直接拒绝</p>
<p>针对2.2 - &gt; 线程池状态==SHUTDOWN，且firstTask == null， 但队列为空， 不允许新增Worker<br>当firstTask为null时，说明调用addWorker()目的不是为了处理新增任务<br>那么其目的应该是为了处理剩余任务，即队列中的任务，而一旦队列为空，那也没必要新增Worker了</p>
<p>针对1.2 - &gt; 若线程池状态==SHUTDOWN，必须满足firstTask为null且队列非空，才允许新增Worker<br>当线程池状态为SHUTDOWN时(调用shutdown())，此时不允许接收新任务，因此firstTask必须为null<br>但需要处理剩余任务，因此队列必须非空，否则新增的工作线程就无任务可做，那就没意义了<br>结论：传入一个空任务的目的是为了新增工作线程去处理任务队列中的剩余任务</p>
<h3 id="3-Worker类详解"><a href="#3-Worker类详解" class="headerlink" title="3. Worker类详解"></a>3. Worker类详解</h3><p>worker包装了任务的调度，用于封装工作线程和任务并管理工作线程的中断状态等功能</p>
<blockquote>
<p>由于工作线程和worker实例是一对一的关系，因为可以简单的理解工作线程等价于worker，尤其是谈及数量时，比如创建工作线程实际上就是创建一个worker</p>
</blockquote>
<p>线程在线程池执行任务的工作流程：</p>
<ol>
<li><p>工作线程开始执行前，需先对worker加锁，任务完成解锁</p>
</li>
<li><p>任务执行前后分别执行beforeExecute()和afterExecute()方法</p>
</li>
<li><p>执行中遇到异常会向外抛出，线程是否死亡取决于您对于异常的处理</p>
</li>
<li><p>每个任务执行完后，当前工作线程任务完成数自增，同时会循环调用getTask()从任务队列中反复获取任务并执行，无任务可执行时线程会阻塞在该方法上</p>
</li>
<li><p>当工作线程因各种理由退出时，会执行processWorkerExit()回收线程(核心是将该worker从workers集合中移除，注意之前worker已经退出任务循环，因此已经不再做工了，从集合移除后就方便gc了)</p>
</li>
</ol>
<p><strong>问：worker中断如何控制的</strong></p>
<ol>
<li><p>当工作线程真正开始执行之前，不允许被中断</p>
</li>
<li><p>当工作线程正在执行任务时，不允许被中断</p>
</li>
<li><p>当工作线程正等待从任务队列中获取任务getTask()时才能被中断</p>
</li>
<li><p>调用interruptIdleWorkers()中断空闲线程时必须先获得worker锁</p>
</li>
</ol>
<p><strong>问：为什么Worker不被设计成可重入锁？</strong></p>
<p>由于在动态控制方法中可能会中断线程，比如调用interruptIdleWorkers()，由此该方法在执行interrupt()之前会调用worker.tryLock()，若此时允许重入，就会导致线程被意外中断，这跟当工作线程正在执行任务时，不允许被中断准则是相违背的</p>
<h2 id="IV-问题解答"><a href="#IV-问题解答" class="headerlink" title="IV. 问题解答"></a>IV. 问题解答</h2><h3 id="1-如何创建线程池"><a href="#1-如何创建线程池" class="headerlink" title="1. 如何创建线程池"></a>1. 如何创建线程池</h3><p>直接根据构造方法创建</p>
<figure class="highlight java hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">java.util.concurrent.ThreadPoolExecutor#ThreadPoolExecutor(int, int, long,</span><br><span class="line">    java.util.concurrent.TimeUnit, </span><br><span class="line">    java.util.concurrent.BlockingQueue&lt;java.lang.Runnable&gt;,</span><br><span class="line">    java.util.concurrent.ThreadFactory,</span><br><span class="line">    java.util.concurrent.RejectedExecutionHandler)</span><br></pre></td></tr></table></figure>
<p>利用 Executors 创建线程池</p>
<figure class="highlight hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">java.util.concurrent.Executors#newFixedThreadPool(int)</span><br><span class="line"></span><br><span class="line">java.util.concurrent.Executors#newWorkStealingPool(int)</span><br><span class="line"></span><br><span class="line">java.util.concurrent.Executors#newSingleThreadExecutor()</span><br><span class="line"></span><br><span class="line">java.util.concurrent.Executors#newCachedThreadPool()</span><br><span class="line"></span><br><span class="line">java.util.concurrent.Executors#newSingleThreadScheduledExecutor()</span><br><span class="line"></span><br><span class="line">java.util.concurrent.Executors#newScheduledThreadPool(int)</span><br><span class="line"></span><br><span class="line">java.util.concurrent.Executors#unconfigurableExecutorService</span><br></pre></td></tr></table></figure>
<h3 id="2-线程池的适用场景"><a href="#2-线程池的适用场景" class="headerlink" title="2. 线程池的适用场景"></a>2. 线程池的适用场景</h3><p><strong>优点</strong></p>
<p>减少了创建和销毁线程的次数，每个工作线程都可以被重复利用，可执行多个任务<br>可以根据系统的承受能力，调整线程池中工作线线程的数量</p>
<p><strong>使用线程池场景</strong></p>
<p>我们将线程进行拆分，创建线程耗时T1, 线程执行耗时T2, 销毁线程耗时T3</p>
<p>如果你的场景中，提交线程执行的任务非常频繁，且具体的执行耗时较短，即 T1 + T3 &gt; T2, 这种场景下使用线程池可以带来明显的性能提升</p>
<p>一般来说，如果不是你的任务只偶尔的运行几次，那么绝大部分场景都适合用线程池来处理</p>
<h3 id="3-如何使用线程池"><a href="#3-如何使用线程池" class="headerlink" title="3. 如何使用线程池"></a>3. 如何使用线程池</h3><p>创建线程池，提交任务</p>
<ul>
<li>execute 适用于提交没有返回结果的任务</li>
<li>submit 适用于提交有返回结果的任务， 返回一个Futrure的包装类</li>
</ul>
<h3 id="4-线程池实现原理-amp-任务提交后的流程"><a href="#4-线程池实现原理-amp-任务提交后的流程" class="headerlink" title="4. 线程池实现原理 &amp; 任务提交后的流程"></a>4. 线程池实现原理 &amp; 任务提交后的流程</h3><p>在实现原理中会穿插上任务提交后的流程，所以就放在一起了</p>
<p>首先从提交一个任务开始：</p>
<ul>
<li>首先判断工作线程数是否小于核心工作线程数，是则直接创建工作线程执行</li>
<li>否，则将任务丢入任务队列中</li>
<li>若任务队列已满，且工作线程数 &lt; 最大工作线程数，则直接创建工作线程执行任务</li>
<li>若队列满，且工作线程数达到最大值，则采用拒绝任务策略</li>
</ul>
<p>其中上面的任务进队or创建线程执行，都需要关注线程池的状态，每个状态对应的原则</p>
<table>
<thead>
<tr>
<th>状态</th>
<th>说明</th>
<th>限制</th>
</tr>
</thead>
<tbody>
<tr>
<td>RUNNING</td>
<td>运行状态</td>
<td>线程池会接收新提交任务和执行队列任务</td>
</tr>
<tr>
<td>SHUTDOWN</td>
<td>关闭状态</td>
<td>线程池不再接收新任务，但还会继续执行队列任务</td>
</tr>
<tr>
<td>STOP</td>
<td>停止状态</td>
<td>不再接收新任务，不会再执行队列任务，并会中断正在执行中的任务</td>
</tr>
<tr>
<td>TIDYING</td>
<td>整理状态</td>
<td>所有任务都被终止，工作线程数为0，期间会调用钩子方法terminated()</td>
</tr>
<tr>
<td>TERMINATED</td>
<td>终止状态</td>
<td>线程池terminated()方法已经调用完成</td>
</tr>
</tbody>
</table>
<p>接着上面，工作线程执行完毕之后，会尝试从任务队列中获取任务来执行，如果队列为空，则阻塞；此时工作线程空闲</p>
<p>根据工作线程的回收机制</p>
<ul>
<li>允许回收核心工作线程时，将所有空闲时间大于keepAliveTime的线程回收掉</li>
<li>不允许回收核心工作线程，回收空闲时间大于keepAliveTime的线程，知道工作线程数量为核心工作线程数</li>
</ul>
<h3 id="5-异常状况处理"><a href="#5-异常状况处理" class="headerlink" title="5. 异常状况处理"></a>5. 异常状况处理</h3><p><strong>submit()异常处理</strong></p>
<ol>
<li>异常会保存在Future对象的ExecutionException中，可以在调用get()使用try-catch方式捕获，有N个任务有异常就会抛出来N个异常，但不会终止当前工作线程</li>
<li>单独设置UncaughtExceptionHandler没卵用，但结合(3)使用就有效</li>
<li>允许在submit()方法内部用try-catch捕获该异常，同样不会终止当前线程</li>
<li>若想在内部处理异常，还可以重写afterExecute()方法，</li>
</ol>
<p><strong>execute()异常处理</strong></p>
<ol>
<li>默认会在execute()方法内部直接抛出异常，注意这不会中断线程池运行，但会终止当前工作线程，并重新创建新的工作线程执行该任务</li>
<li>允许在execute()方法内部用try-catch捕获该异常，好处是不会终止当前线程并重新创建一个新的线程了</li>
<li>重写afterExecute()方法</li>
<li>还可以设置UncaughtExceptionHandler</li>
</ol>
<p>一个实例如下:</p>
<figure class="highlight java hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">ThreadPoolExecutor threadPoolExecutor = <span class="hljs-keyword">new</span> ThreadPoolExecutor(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, TimeUnit.SECONDS, <span class="hljs-keyword">new</span> LinkedBlockingQueue(), </span><br><span class="line">    <span class="hljs-comment">//我们自定义一个线程工厂和重写线程的setUncaughtExceptionHandler方法</span></span><br><span class="line">    <span class="hljs-keyword">new</span> ThreadFactory() &#123;</span><br><span class="line">        <span class="hljs-keyword">final</span> AtomicInteger threadNumber = <span class="hljs-keyword">new</span> AtomicInteger(<span class="hljs-number">1</span>);</span><br><span class="line">        <span class="hljs-function"><span class="hljs-keyword">public</span> Thread <span class="hljs-title">newThread</span><span class="hljs-params">(Runnable r)</span> </span>&#123;</span><br><span class="line">            Thread thread = <span class="hljs-keyword">new</span> Thread(Thread.currentThread().getThreadGroup(), r, <span class="hljs-string">"thread-"</span></span><br><span class="line">                    + (threadNumber.getAndIncrement()));</span><br><span class="line">            thread.setUncaughtExceptionHandler((t,e) -&gt; System.out.println(e));</span><br><span class="line">            <span class="hljs-keyword">return</span> thread;</span><br><span class="line">        &#125;</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>
<h3 id="6-线程池关闭"><a href="#6-线程池关闭" class="headerlink" title="6. 线程池关闭"></a>6. 线程池关闭</h3><p>关闭线程池主要有两种方式，两者的区别是：</p>
<ul>
<li>shutdown() : 队列剩余任务全部执行完毕再终止</li>
<li>shutdownNow() : 放弃执行队列剩余任务，但会将它们返回</li>
</ul>
<p>两者的共性在于：</p>
<ul>
<li>正在执行中的任务会继续执行，不会被终止或放弃</li>
<li>新提交的任务会被直接拒绝</li>
</ul>
<h2 id="V-其他"><a href="#V-其他" class="headerlink" title="V. 其他"></a>V. 其他</h2><h3 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h3><ul>
<li><a href="http://blog.csdn.net/wolf909867753/article/details/77500625" target="_blank" rel="noopener">Java-线程池专题（什么是线程池，如何使用，为什么要用）</a></li>
<li><a href="https://juejin.im/entry/5a80065f5188257a7f1da4c1?utm_source=gold_browser_extension" target="_blank" rel="noopener">并发番@ThreadPoolExecutor</a></li>
</ul>
<h3 id="个人博客：-Z-blog"><a href="#个人博客：-Z-blog" class="headerlink" title="个人博客： Z+|blog"></a>个人博客： <a href="https://liuyueyi.github.io/hexblog" target="_blank" rel="noopener">Z+|blog</a></h3><p>基于hexo + github pages搭建的个人博客，记录所有学习和工作中的博文，欢迎大家前去逛逛</p>
<h3 id="声明"><a href="#声明" class="headerlink" title="声明"></a>声明</h3><p>尽信书则不如，已上内容，纯属一家之言，因本人能力一般，见识有限，如发现bug或者有更好的建议，随时欢迎批评指正，我的微博地址: <a href="https://weibo.com/p/1005052169825577/home" target="_blank" rel="noopener">小灰灰Blog</a></p>
<h3 id="扫描关注"><a href="#扫描关注" class="headerlink" title="扫描关注"></a>扫描关注</h3><p><img src="https://s17.mogucdn.com/mlcdn/c45406/180209_74fic633aebgh5dgfhid2fiiggc99_1220x480.png" alt="QrCode"></p>


            
        </div>
        
        <div class="level is-size-7 is-uppercase">
            <div class="level-start">
                <div class="level-item">
                    <span class="is-size-6 has-text-grey has-mr-7">#</span>
                    <a class="has-link-grey -link" href="/hexblog/tags/Java/">Java</a>, <a class="has-link-grey -link" href="/hexblog/tags/并发/">并发</a>
                </div>
            </div>
        </div>
        
        
        
        <div class="bdsharebuttonbox">
    <a href="#" class="bds_more" data-cmd="more"></a>
    <a href="#" class="bds_qzone" data-cmd="qzone" title="分享到QQ空间"></a>
    <a href="#" class="bds_tsina" data-cmd="tsina" title="分享到新浪微博"></a>
    <a href="#" class="bds_tqq" data-cmd="tqq" title="分享到腾讯微博"></a>
    <a href="#" class="bds_renren" data-cmd="renren" title="分享到人人网"></a>
    <a href="#" class="bds_weixin" data-cmd="weixin" title="分享到微信"></a>
</div>
<script>window._bd_share_config = { "common": { "bdSnsKey": {}, "bdText": "", "bdMini": "2", "bdPic": "", "bdStyle": "0", "bdSize": "16" }, "share": {} }; with (document) 0[(getElementsByTagName('head')[0] || body).appendChild(createElement('script')).src = 'http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion=' + ~(-new Date() / 36e5)];</script>
        
    </div>
</div>



<div class="card">
    <div class="card-content">
        <h3 class="menu-label has-text-centered">喜欢这篇文章？打赏一下作者吧</h3>
        <div class="buttons is-centered">
            
                
<a class="button is-info donate">
    <span class="icon is-small">
        <i class="fab fa-alipay"></i>
    </span>
    <span>支付宝</span>
    <div class="qrcode"><img src="https://s3.mogucdn.com/mlcdn/c45406/180104_0e6afl33b23lacj6ji2d7d060aiak_798x800.png" alt="支付宝"></div>
</a>

                
                
<a class="button is-success donate">
    <span class="icon is-small">
        <i class="fab fa-weixin"></i>
    </span>
    <span>微信</span>
    <div class="qrcode"><img src="https://s11.mogucdn.com/mlcdn/c45406/180527_09cafb94a5g3lbd5ik6ke0hf649ff_800x798.jpg" alt="微信"></div>
</a>

                
        </div>
    </div>
</div>



<div class="card card-transparent">
    <div class="level post-navigation is-flex-wrap is-mobile">
        
        <div class="level-start">
            <a class="level level-item has-link-grey  article-nav-prev" href="/hexblog/2018/03/08/JQuery-实战笔记一/">
                <i class="level-item fas fa-chevron-left"></i>
                <span class="level-item">JQuery 实战笔记一</span>
            </a>
        </div>
        
        
        <div class="level-end">
            <a class="level level-item has-link-grey  article-nav-next" href="/hexblog/2018/03/05/报警系统QuickAlarm之默认报警规则扩展/">
                <span class="level-item">7. 报警系统QuickAlarm之默认报警规则扩展</span>
                <i class="level-item fas fa-chevron-right"></i>
            </a>
        </div>
        
    </div>
</div>



<div class="card">
    <div class="card-content">
        <h3 class="title is-5 has-text-weight-normal">评论</h3>
        
<div id="comment-container"></div>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/gitalk@1.4.1/dist/gitalk.css">
<script src="https://cdn.jsdelivr.net/npm/gitalk@1.4.1/dist/gitalk.min.js"></script>
<script>
    var gitalk = new Gitalk({
        clientID: 'f4c5b85c7c1ceb8fbe2d',
        clientSecret: 'e8c365a05e6ab22272bee0b79ab27f69ff10a43a',
        id: '0c6cacbf5720b0550e17217dccc0e0b8',
        repo: 'hexblog',
        owner: 'liuyueyi',
        admin: "liuyueyi"
    })
    gitalk.render('comment-container')
</script>

    </div>
</div>
</div>
                




<div class="column is-4-tablet is-4-desktop is-3-widescreen  has-order-1 column-left ">
    
        
<div class="card widget">
    <div class="card-content card-info">
        <nav class="level">
            <div class="level-item has-text-centered">
                <div>
                    
                        <img class="image is-128x128 has-mb-6" src="/hexblog/images/avatar.jpg" alt="一灰灰Blog">
                    
                    
                    <p class="is-size-4 is-block">
                        一灰灰Blog
                    </p>
                    
                    
                    <p class="is-size-6 is-block">
                        Java，服务器后端开发
                    </p>
                    
                    
                    <p class="is-size-6 is-flex is-flex-center has-text-grey">
                        <i class="fas fa-map-marker-alt has-mr-7"></i>
                        <span>Wuhan, China</span>
                    </p>
                    
                </div>
            </div>
        </nav>
        <nav class="level is-mobile">
            <div class="level-item has-text-centered is-marginless">
                <div>
                    
                    <p class="heading">
                        文章
                    </p>
                    <a href="/hexblog/archives">
                    <p class="title has-text-weight-normal">
                        269
                    </p>
                    </a>
                </div>
            </div>
            <div class="level-item has-text-centered is-marginless">
                <div>
                    
                    <p class="heading">
                        分类
                    </p>
                    <a href="/hexblog/categories">
                        <p class="title has-text-weight-normal">
                            70
                        </p>
                    </a>
                </div>
            </div>
            <div class="level-item has-text-centered is-marginless">
                <div>
                
                    <p class="heading">
                        标签
                    </p>
                    <a href="/hexblog/tags">
                    <p class="title has-text-weight-normal">
                        74
                    </p>
                    </a>
                </div>
            </div>
        </nav>
        <div class="level">
            <a class="level-item button is-link is-rounded" href="https://github.com/liuyueyi" target="_blank">
                关注我</a>
        </div>
        
        
        <div class="level is-mobile">
            
            <a class="level-item button is-white is-marginless" target="_blank"
                title="Github" href="https://github.com/liuyueyi">
                
                <i class="fab fa-github"></i>
                
            </a>
            
            <a class="level-item button is-white is-marginless" target="_blank"
                title="Gitee" href="https://gitee.com/liuyueyi">
                
                <i class="fab fa-gg"></i>
                
            </a>
            
            <a class="level-item button is-white is-marginless" target="_blank"
                title="Weibo" href="https://weibo.com/p/1005052169825577/home">
                
                <i class="fab fa-weibo"></i>
                
            </a>
            
            <a class="level-item button is-white is-marginless" target="_blank"
                title="weixin" href="https://s10.mogucdn.com/mlcdn/c45406/171229_1cgld3igbelkbc70cd8af1j3809kb_150x150.jpg">
                
                <i class="fab fa-weixin"></i>
                
            </a>
            
            <a class="level-item button is-white is-marginless" target="_blank"
                title="RSS" href="/hexblog/atom.xml">
                
                <i class="fas fa-rss"></i>
                
            </a>
            
        </div>
        
    </div>
</div>
    
        
    
        

<div class="card widget">
    <div class="card-content">
        <div class="menu">
        <h3 class="menu-label">
            链接
        </h3>
        <ul class="menu-list">
        
            <li>
                <a class="level is-mobile" href="http://spring.hhui.top" target="_blank">
                    <span class="level-left">
                        <span class="level-item">SpringBlog</span>
                    </span>
                    <span class="level-right">
                        <span class="level-item tag">spring.hhui.top</span>
                    </span>
                </a>
            </li>
        
            <li>
                <a class="level is-mobile" href="https://github.com/liuyueyi" target="_blank">
                    <span class="level-left">
                        <span class="level-item">GitHub</span>
                    </span>
                    <span class="level-right">
                        <span class="level-item tag">github.com</span>
                    </span>
                </a>
            </li>
        
            <li>
                <a class="level is-mobile" href="https://zweb.hhui.top" target="_blank">
                    <span class="level-left">
                        <span class="level-item">多媒体工具小站</span>
                    </span>
                    <span class="level-right">
                        <span class="level-item tag">zweb.hhui.top</span>
                    </span>
                </a>
            </li>
        
            <li>
                <a class="level is-mobile" href="https://mweb.hhui.top" target="_blank">
                    <span class="level-left">
                        <span class="level-item">每日十首古诗词</span>
                    </span>
                    <span class="level-right">
                        <span class="level-item tag">mweb.hhui.top</span>
                    </span>
                </a>
            </li>
        
        </ul>
        </div>
    </div>
</div>


    
        
<div class="card widget">
    <div class="card-content">
        <h3 class="menu-label">
            最新文章
        </h3>
        
        <article class="media">
            
            <div class="media-content">
                <div class="content">
                    <div><time class="has-text-grey is-size-7 is-uppercase" datetime="2020-03-28T11:27:12.000Z">2020-03-28</time></div>
                    <a href="/hexblog/2020/03/28/200328-MongoDb系列教程九-文档-Document-查询基础篇/" class="has-link-black-ter is-size-6">200328-MongoDb系列教程九：文档 Document 查询基础篇</a>
                    <p class="is-size-7 is-uppercase">
                        <a class="has-link-grey -link" href="/hexblog/categories/DB/">DB</a> / <a class="has-link-grey -link" href="/hexblog/categories/DB/Mongo/">Mongo</a>
                    </p>
                </div>
            </div>
        </article>
        
        <article class="media">
            
            <div class="media-content">
                <div class="content">
                    <div><time class="has-text-grey is-size-7 is-uppercase" datetime="2020-03-27T03:04:36.000Z">2020-03-27</time></div>
                    <a href="/hexblog/2020/03/27/200327-MongoDb系列教程八-文档-Document-更新姿势/" class="has-link-black-ter is-size-6">200327-MongoDb系列教程八：文档 Document 更新姿势</a>
                    <p class="is-size-7 is-uppercase">
                        <a class="has-link-grey -link" href="/hexblog/categories/DB/">DB</a> / <a class="has-link-grey -link" href="/hexblog/categories/DB/Mongo/">Mongo</a>
                    </p>
                </div>
            </div>
        </article>
        
        <article class="media">
            
            <div class="media-content">
                <div class="content">
                    <div><time class="has-text-grey is-size-7 is-uppercase" datetime="2020-03-26T10:02:03.000Z">2020-03-26</time></div>
                    <a href="/hexblog/2020/03/26/200326-MongoDb系列教程七-文档-Document-删除姿势/" class="has-link-black-ter is-size-6">200326-MongoDb系列教程七：文档 Document 删除姿势</a>
                    <p class="is-size-7 is-uppercase">
                        <a class="has-link-grey -link" href="/hexblog/categories/DB/">DB</a> / <a class="has-link-grey -link" href="/hexblog/categories/DB/Mongo/">Mongo</a>
                    </p>
                </div>
            </div>
        </article>
        
        <article class="media">
            
            <div class="media-content">
                <div class="content">
                    <div><time class="has-text-grey is-size-7 is-uppercase" datetime="2020-03-26T09:04:06.000Z">2020-03-26</time></div>
                    <a href="/hexblog/2020/03/26/200326-MongoDb系列教程六-文档-Document-插入姿势/" class="has-link-black-ter is-size-6">200326-MongoDb系列教程六：文档 Document 插入姿势</a>
                    <p class="is-size-7 is-uppercase">
                        <a class="has-link-grey -link" href="/hexblog/categories/DB/">DB</a> / <a class="has-link-grey -link" href="/hexblog/categories/DB/Mongo/">Mongo</a>
                    </p>
                </div>
            </div>
        </article>
        
        <article class="media">
            
            <div class="media-content">
                <div class="content">
                    <div><time class="has-text-grey is-size-7 is-uppercase" datetime="2020-03-26T08:52:20.000Z">2020-03-26</time></div>
                    <a href="/hexblog/2020/03/26/200326-MongoDb系列教程五-集合-Collection/" class="has-link-black-ter is-size-6">200326-MongoDb系列教程五：集合 Collection</a>
                    <p class="is-size-7 is-uppercase">
                        <a class="has-link-grey -link" href="/hexblog/categories/DB/">DB</a> / <a class="has-link-grey -link" href="/hexblog/categories/DB/Mongo/">Mongo</a>
                    </p>
                </div>
            </div>
        </article>
        
    </div>
</div>

    
        
<div class="card widget">
    <div class="card-content">
        <h3 class="menu-label">
            标签云
        </h3>
        <a href="/hexblog/tags/Android/" style="font-size: 10px;">Android</a> <a href="/hexblog/tags/AutoCloseable/" style="font-size: 10px;">AutoCloseable</a> <a href="/hexblog/tags/BloomFilter/" style="font-size: 10px;">BloomFilter</a> <a href="/hexblog/tags/BugFix/" style="font-size: 10.63px;">BugFix</a> <a href="/hexblog/tags/Bugfix/" style="font-size: 10.63px;">Bugfix</a> <a href="/hexblog/tags/Docker/" style="font-size: 11.88px;">Docker</a> <a href="/hexblog/tags/FastJson/" style="font-size: 10px;">FastJson</a> <a href="/hexblog/tags/Git/" style="font-size: 11.25px;">Git</a> <a href="/hexblog/tags/Groovy/" style="font-size: 10px;">Groovy</a> <a href="/hexblog/tags/Guava/" style="font-size: 11.25px;">Guava</a> <a href="/hexblog/tags/HashMap/" style="font-size: 10px;">HashMap</a> <a href="/hexblog/tags/IO/" style="font-size: 10.63px;">IO</a> <a href="/hexblog/tags/ImageMagic/" style="font-size: 10.63px;">ImageMagic</a> <a href="/hexblog/tags/InfluxDB/" style="font-size: 16.88px;">InfluxDB</a> <a href="/hexblog/tags/InputStream/" style="font-size: 10px;">InputStream</a> <a href="/hexblog/tags/JDK/" style="font-size: 15px;">JDK</a> <a href="/hexblog/tags/JVM/" style="font-size: 11.25px;">JVM</a> <a href="/hexblog/tags/Java/" style="font-size: 20px;">Java</a> <a href="/hexblog/tags/JavaAgent/" style="font-size: 10.63px;">JavaAgent</a> <a href="/hexblog/tags/JavaWeb/" style="font-size: 10.63px;">JavaWeb</a> <a href="/hexblog/tags/Jquery/" style="font-size: 10px;">Jquery</a> <a href="/hexblog/tags/Linux/" style="font-size: 15px;">Linux</a> <a href="/hexblog/tags/List/" style="font-size: 10px;">List</a> <a href="/hexblog/tags/MD5/" style="font-size: 10px;">MD5</a> <a href="/hexblog/tags/Map/" style="font-size: 10px;">Map</a> <a href="/hexblog/tags/Maven/" style="font-size: 10px;">Maven</a> <a href="/hexblog/tags/Mongo/" style="font-size: 10.63px;">Mongo</a> <a href="/hexblog/tags/MongoDB/" style="font-size: 10px;">MongoDB</a> <a href="/hexblog/tags/MongoDb/" style="font-size: 14.38px;">MongoDb</a> <a href="/hexblog/tags/MySql/" style="font-size: 10.63px;">MySql</a> <a href="/hexblog/tags/Mybatis/" style="font-size: 10.63px;">Mybatis</a> <a href="/hexblog/tags/Mysql/" style="font-size: 16.25px;">Mysql</a> <a href="/hexblog/tags/Nginx/" style="font-size: 11.25px;">Nginx</a> <a href="/hexblog/tags/OGNL/" style="font-size: 11.25px;">OGNL</a> <a href="/hexblog/tags/ProtoStuff/" style="font-size: 10.63px;">ProtoStuff</a> <a href="/hexblog/tags/Python/" style="font-size: 19.38px;">Python</a> <a href="/hexblog/tags/QuickAlarm/" style="font-size: 10px;">QuickAlarm</a> <a href="/hexblog/tags/RabbitMQ/" style="font-size: 13.75px;">RabbitMQ</a> <a href="/hexblog/tags/ReactJS/" style="font-size: 10px;">ReactJS</a> <a href="/hexblog/tags/Redis/" style="font-size: 14.38px;">Redis</a> <a href="/hexblog/tags/Shell/" style="font-size: 15.63px;">Shell</a> <a href="/hexblog/tags/Socket/" style="font-size: 10px;">Socket</a> <a href="/hexblog/tags/Solr/" style="font-size: 10px;">Solr</a> <a href="/hexblog/tags/Spring/" style="font-size: 18.75px;">Spring</a> <a href="/hexblog/tags/SpringBoot/" style="font-size: 10px;">SpringBoot</a> <a href="/hexblog/tags/Vue/" style="font-size: 10px;">Vue</a> <a href="/hexblog/tags/WebSocket/" style="font-size: 10px;">WebSocket</a> <a href="/hexblog/tags/Yaml/" style="font-size: 10px;">Yaml</a> <a href="/hexblog/tags/css/" style="font-size: 11.25px;">css</a> <a href="/hexblog/tags/ffmpeg/" style="font-size: 10px;">ffmpeg</a> <a href="/hexblog/tags/gitalk/" style="font-size: 10px;">gitalk</a> <a href="/hexblog/tags/hexo/" style="font-size: 10px;">hexo</a> <a href="/hexblog/tags/jdk/" style="font-size: 10px;">jdk</a> <a href="/hexblog/tags/logger/" style="font-size: 10px;">logger</a> <a href="/hexblog/tags/markdown/" style="font-size: 10px;">markdown</a> <a href="/hexblog/tags/python/" style="font-size: 10px;">python</a> <a href="/hexblog/tags/time/" style="font-size: 10px;">time</a> <a href="/hexblog/tags/乱码/" style="font-size: 10px;">乱码</a> <a href="/hexblog/tags/二维码/" style="font-size: 10px;">二维码</a> <a href="/hexblog/tags/分库分表/" style="font-size: 10px;">分库分表</a> <a href="/hexblog/tags/反射/" style="font-size: 11.25px;">反射</a> <a href="/hexblog/tags/工具/" style="font-size: 12.5px;">工具</a> <a href="/hexblog/tags/并发/" style="font-size: 11.25px;">并发</a> <a href="/hexblog/tags/序列化/" style="font-size: 10px;">序列化</a> <a href="/hexblog/tags/手记/" style="font-size: 13.13px;">手记</a> <a href="/hexblog/tags/技术方案/" style="font-size: 18.13px;">技术方案</a> <a href="/hexblog/tags/指南/" style="font-size: 13.13px;">指南</a> <a href="/hexblog/tags/教程/" style="font-size: 17.5px;">教程</a> <a href="/hexblog/tags/方案设计/" style="font-size: 10px;">方案设计</a> <a href="/hexblog/tags/时区/" style="font-size: 10px;">时区</a> <a href="/hexblog/tags/时间窗口/" style="font-size: 11.25px;">时间窗口</a> <a href="/hexblog/tags/爬虫/" style="font-size: 12.5px;">爬虫</a> <a href="/hexblog/tags/问题记录/" style="font-size: 10px;">问题记录</a> <a href="/hexblog/tags/随笔/" style="font-size: 10px;">随笔</a>
    </div>
</div>

    
        <div class="card widget">
    <div class="card-content">
        <div class="menu">
            <h3 class="menu-label">
                标签
            </h3>
            <div class="field is-grouped is-grouped-multiline">
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Android/">
                        <span class="tag">Android</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/AutoCloseable/">
                        <span class="tag">AutoCloseable</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/BloomFilter/">
                        <span class="tag">BloomFilter</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/BugFix/">
                        <span class="tag">BugFix</span>
                        <span class="tag is-grey">2</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Bugfix/">
                        <span class="tag">Bugfix</span>
                        <span class="tag is-grey">2</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Docker/">
                        <span class="tag">Docker</span>
                        <span class="tag is-grey">4</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/FastJson/">
                        <span class="tag">FastJson</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Git/">
                        <span class="tag">Git</span>
                        <span class="tag is-grey">3</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Groovy/">
                        <span class="tag">Groovy</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Guava/">
                        <span class="tag">Guava</span>
                        <span class="tag is-grey">3</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/HashMap/">
                        <span class="tag">HashMap</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/IO/">
                        <span class="tag">IO</span>
                        <span class="tag is-grey">2</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/ImageMagic/">
                        <span class="tag">ImageMagic</span>
                        <span class="tag is-grey">2</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/InfluxDB/">
                        <span class="tag">InfluxDB</span>
                        <span class="tag is-grey">16</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/InputStream/">
                        <span class="tag">InputStream</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/JDK/">
                        <span class="tag">JDK</span>
                        <span class="tag is-grey">11</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/JVM/">
                        <span class="tag">JVM</span>
                        <span class="tag is-grey">3</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Java/">
                        <span class="tag">Java</span>
                        <span class="tag is-grey">59</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/JavaAgent/">
                        <span class="tag">JavaAgent</span>
                        <span class="tag is-grey">2</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/JavaWeb/">
                        <span class="tag">JavaWeb</span>
                        <span class="tag is-grey">2</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Jquery/">
                        <span class="tag">Jquery</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Linux/">
                        <span class="tag">Linux</span>
                        <span class="tag is-grey">11</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/List/">
                        <span class="tag">List</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/MD5/">
                        <span class="tag">MD5</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Map/">
                        <span class="tag">Map</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Maven/">
                        <span class="tag">Maven</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Mongo/">
                        <span class="tag">Mongo</span>
                        <span class="tag is-grey">2</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/MongoDB/">
                        <span class="tag">MongoDB</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/MongoDb/">
                        <span class="tag">MongoDb</span>
                        <span class="tag is-grey">9</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/MySql/">
                        <span class="tag">MySql</span>
                        <span class="tag is-grey">2</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Mybatis/">
                        <span class="tag">Mybatis</span>
                        <span class="tag is-grey">2</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Mysql/">
                        <span class="tag">Mysql</span>
                        <span class="tag is-grey">15</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Nginx/">
                        <span class="tag">Nginx</span>
                        <span class="tag is-grey">3</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/OGNL/">
                        <span class="tag">OGNL</span>
                        <span class="tag is-grey">3</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/ProtoStuff/">
                        <span class="tag">ProtoStuff</span>
                        <span class="tag is-grey">2</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Python/">
                        <span class="tag">Python</span>
                        <span class="tag is-grey">32</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/QuickAlarm/">
                        <span class="tag">QuickAlarm</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/RabbitMQ/">
                        <span class="tag">RabbitMQ</span>
                        <span class="tag is-grey">8</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/ReactJS/">
                        <span class="tag">ReactJS</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Redis/">
                        <span class="tag">Redis</span>
                        <span class="tag is-grey">9</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Shell/">
                        <span class="tag">Shell</span>
                        <span class="tag is-grey">13</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Socket/">
                        <span class="tag">Socket</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Solr/">
                        <span class="tag">Solr</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Spring/">
                        <span class="tag">Spring</span>
                        <span class="tag is-grey">25</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/SpringBoot/">
                        <span class="tag">SpringBoot</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Vue/">
                        <span class="tag">Vue</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/WebSocket/">
                        <span class="tag">WebSocket</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Yaml/">
                        <span class="tag">Yaml</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/css/">
                        <span class="tag">css</span>
                        <span class="tag is-grey">3</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/ffmpeg/">
                        <span class="tag">ffmpeg</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/gitalk/">
                        <span class="tag">gitalk</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/hexo/">
                        <span class="tag">hexo</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/jdk/">
                        <span class="tag">jdk</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/logger/">
                        <span class="tag">logger</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/markdown/">
                        <span class="tag">markdown</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/python/">
                        <span class="tag">python</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/time/">
                        <span class="tag">time</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/乱码/">
                        <span class="tag">乱码</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/二维码/">
                        <span class="tag">二维码</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/分库分表/">
                        <span class="tag">分库分表</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/反射/">
                        <span class="tag">反射</span>
                        <span class="tag is-grey">3</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/工具/">
                        <span class="tag">工具</span>
                        <span class="tag is-grey">5</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/并发/">
                        <span class="tag">并发</span>
                        <span class="tag is-grey">3</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/序列化/">
                        <span class="tag">序列化</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/手记/">
                        <span class="tag">手记</span>
                        <span class="tag is-grey">6</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/技术方案/">
                        <span class="tag">技术方案</span>
                        <span class="tag is-grey">22</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/指南/">
                        <span class="tag">指南</span>
                        <span class="tag is-grey">6</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/教程/">
                        <span class="tag">教程</span>
                        <span class="tag is-grey">20</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/方案设计/">
                        <span class="tag">方案设计</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/时区/">
                        <span class="tag">时区</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/时间窗口/">
                        <span class="tag">时间窗口</span>
                        <span class="tag is-grey">3</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/爬虫/">
                        <span class="tag">爬虫</span>
                        <span class="tag is-grey">5</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/问题记录/">
                        <span class="tag">问题记录</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/随笔/">
                        <span class="tag">随笔</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
            </div>
        </div>
    </div>
</div>
    
    
        <div class="column-right-shadow is-hidden-widescreen ">
        
            
<div class="card widget">
    <div class="card-content">
        <div class="menu">
            <h3 class="menu-label">
                分类
            </h3>
            <ul class="menu-list">
            <li>
        <a class="level is-marginless" href="/hexblog/categories/DB/">
            <span class="level-start">
                <span class="level-item">DB</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">41</span>
            </span>
        </a><ul><li>
        <a class="level is-marginless" href="/hexblog/categories/DB/InfluxDB/">
            <span class="level-start">
                <span class="level-item">InfluxDB</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">16</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/DB/Mongo/">
            <span class="level-start">
                <span class="level-item">Mongo</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">11</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/DB/Mysql/">
            <span class="level-start">
                <span class="level-item">Mysql</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">13</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/DB/分库分表/">
            <span class="level-start">
                <span class="level-item">分库分表</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li></ul></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Java/">
            <span class="level-start">
                <span class="level-item">Java</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">52</span>
            </span>
        </a><ul><li>
        <a class="level is-marginless" href="/hexblog/categories/Java/Agent/">
            <span class="level-start">
                <span class="level-item">Agent</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">2</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Java/Android/">
            <span class="level-start">
                <span class="level-item">Android</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Java/Bugfix/">
            <span class="level-start">
                <span class="level-item">Bugfix</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">3</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Java/IO/">
            <span class="level-start">
                <span class="level-item">IO</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">3</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Java/JDK/">
            <span class="level-start">
                <span class="level-item">JDK</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">22</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Java/JVM/">
            <span class="level-start">
                <span class="level-item">JVM</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">9</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Java/JavaWeb/">
            <span class="level-start">
                <span class="level-item">JavaWeb</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">2</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Java/其他/">
            <span class="level-start">
                <span class="level-item">其他</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">4</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Java/问题记录/">
            <span class="level-start">
                <span class="level-item">问题记录</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">6</span>
            </span>
        </a></li></ul></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Python/">
            <span class="level-start">
                <span class="level-item">Python</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">33</span>
            </span>
        </a><ul><li>
        <a class="level is-marginless" href="/hexblog/categories/Python/Mongo/">
            <span class="level-start">
                <span class="level-item">Mongo</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Python/MySql/">
            <span class="level-start">
                <span class="level-item">MySql</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">2</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Python/教程/">
            <span class="level-start">
                <span class="level-item">教程</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">25</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Python/采坑记录/">
            <span class="level-start">
                <span class="level-item">采坑记录</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">2</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Python/项目/">
            <span class="level-start">
                <span class="level-item">项目</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li></ul></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Quick系列/">
            <span class="level-start">
                <span class="level-item">Quick系列</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">30</span>
            </span>
        </a><ul><li>
        <a class="level is-marginless" href="/hexblog/categories/Quick系列/QuickAlarm/">
            <span class="level-start">
                <span class="level-item">QuickAlarm</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">8</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Quick系列/QuickCrawler/">
            <span class="level-start">
                <span class="level-item">QuickCrawler</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">5</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Quick系列/QuickFix/">
            <span class="level-start">
                <span class="level-item">QuickFix</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">6</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Quick系列/QuickMedia/">
            <span class="level-start">
                <span class="level-item">QuickMedia</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">2</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Quick系列/QuickSpi/">
            <span class="level-start">
                <span class="level-item">QuickSpi</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">4</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Quick系列/QuickTask/">
            <span class="level-start">
                <span class="level-item">QuickTask</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">5</span>
            </span>
        </a></li></ul></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Shell/">
            <span class="level-start">
                <span class="level-item">Shell</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">39</span>
            </span>
        </a><ul><li>
        <a class="level is-marginless" href="/hexblog/categories/Shell/CMD/">
            <span class="level-start">
                <span class="level-item">CMD</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">18</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Shell/Docker/">
            <span class="level-start">
                <span class="level-item">Docker</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">4</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Shell/Git/">
            <span class="level-start">
                <span class="level-item">Git</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">3</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Shell/Maven/">
            <span class="level-start">
                <span class="level-item">Maven</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Shell/Ngins/">
            <span class="level-start">
                <span class="level-item">Ngins</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Shell/Nginx/">
            <span class="level-start">
                <span class="level-item">Nginx</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">2</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Shell/环境搭建/">
            <span class="level-start">
                <span class="level-item">环境搭建</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">9</span>
            </span>
        </a></li></ul></li><li>
        <a class="level is-marginless" href="/hexblog/categories/前端/">
            <span class="level-start">
                <span class="level-item">前端</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">8</span>
            </span>
        </a><ul><li>
        <a class="level is-marginless" href="/hexblog/categories/前端/Chrome/">
            <span class="level-start">
                <span class="level-item">Chrome</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/前端/Css/">
            <span class="level-start">
                <span class="level-item">Css</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">3</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/前端/Jquery/">
            <span class="level-start">
                <span class="level-item">Jquery</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/前端/ReactJS/">
            <span class="level-start">
                <span class="level-item">ReactJS</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">2</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/前端/Vue/">
            <span class="level-start">
                <span class="level-item">Vue</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li></ul></li><li>
        <a class="level is-marginless" href="/hexblog/categories/工具/">
            <span class="level-start">
                <span class="level-item">工具</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">9</span>
            </span>
        </a><ul><li>
        <a class="level is-marginless" href="/hexblog/categories/工具/工具类/">
            <span class="level-start">
                <span class="level-item">工具类</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">6</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/工具/插件系列/">
            <span class="level-start">
                <span class="level-item">插件系列</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">3</span>
            </span>
        </a></li></ul></li><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/">
            <span class="level-start">
                <span class="level-item">开源</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">46</span>
            </span>
        </a><ul><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/Guava/">
            <span class="level-start">
                <span class="level-item">Guava</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">2</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/Hexo/">
            <span class="level-start">
                <span class="level-item">Hexo</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/Hystrix/">
            <span class="level-start">
                <span class="level-item">Hystrix</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/Mybatis/">
            <span class="level-start">
                <span class="level-item">Mybatis</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">2</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/OGNL/">
            <span class="level-start">
                <span class="level-item">OGNL</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">3</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/RabbitMQ/">
            <span class="level-start">
                <span class="level-item">RabbitMQ</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">8</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/Redis/">
            <span class="level-start">
                <span class="level-item">Redis</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">3</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/Solr/">
            <span class="level-start">
                <span class="level-item">Solr</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/Spring/">
            <span class="level-start">
                <span class="level-item">Spring</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">24</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/Yaml/">
            <span class="level-start">
                <span class="level-item">Yaml</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li></ul></li><li>
        <a class="level is-marginless" href="/hexblog/categories/火花/">
            <span class="level-start">
                <span class="level-item">火花</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">4</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/随笔/">
            <span class="level-start">
                <span class="level-item">随笔</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">7</span>
            </span>
        </a><ul><li>
        <a class="level is-marginless" href="/hexblog/categories/随笔/idea/">
            <span class="level-start">
                <span class="level-item">idea</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/随笔/吐槽/">
            <span class="level-start">
                <span class="level-item">吐槽</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li></ul></li>
            </ul>
        </div>
    </div>
</div>
        
            <div class="card widget">
    <div class="card-content">
        <div class="menu">
        <h3 class="menu-label">
            归档
        </h3>
        <ul class="menu-list">
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2020/03/">
                <span class="level-start">
                    <span class="level-item">三月 2020</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">14</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2020/02/">
                <span class="level-start">
                    <span class="level-item">二月 2020</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">1</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2020/01/">
                <span class="level-start">
                    <span class="level-item">一月 2020</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">4</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/12/">
                <span class="level-start">
                    <span class="level-item">十二月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">5</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/11/">
                <span class="level-start">
                    <span class="level-item">十一月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">6</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/10/">
                <span class="level-start">
                    <span class="level-item">十月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">2</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/09/">
                <span class="level-start">
                    <span class="level-item">九月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">4</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/08/">
                <span class="level-start">
                    <span class="level-item">八月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">5</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/07/">
                <span class="level-start">
                    <span class="level-item">七月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">11</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/06/">
                <span class="level-start">
                    <span class="level-item">六月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">7</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/05/">
                <span class="level-start">
                    <span class="level-item">五月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">12</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/04/">
                <span class="level-start">
                    <span class="level-item">四月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">7</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/03/">
                <span class="level-start">
                    <span class="level-item">三月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">7</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/02/">
                <span class="level-start">
                    <span class="level-item">二月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">3</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/01/">
                <span class="level-start">
                    <span class="level-item">一月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">14</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/12/">
                <span class="level-start">
                    <span class="level-item">十二月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">8</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/11/">
                <span class="level-start">
                    <span class="level-item">十一月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">10</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/10/">
                <span class="level-start">
                    <span class="level-item">十月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">1</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/09/">
                <span class="level-start">
                    <span class="level-item">九月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">13</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/08/">
                <span class="level-start">
                    <span class="level-item">八月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">11</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/07/">
                <span class="level-start">
                    <span class="level-item">七月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">23</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/06/">
                <span class="level-start">
                    <span class="level-item">六月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">22</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/05/">
                <span class="level-start">
                    <span class="level-item">五月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">11</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/04/">
                <span class="level-start">
                    <span class="level-item">四月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">11</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/03/">
                <span class="level-start">
                    <span class="level-item">三月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">16</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/02/">
                <span class="level-start">
                    <span class="level-item">二月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">10</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/01/">
                <span class="level-start">
                    <span class="level-item">一月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">13</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2017/12/">
                <span class="level-start">
                    <span class="level-item">十二月 2017</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">6</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2017/09/">
                <span class="level-start">
                    <span class="level-item">九月 2017</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">1</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2017/08/">
                <span class="level-start">
                    <span class="level-item">八月 2017</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">3</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2017/07/">
                <span class="level-start">
                    <span class="level-item">七月 2017</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">2</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2017/06/">
                <span class="level-start">
                    <span class="level-item">六月 2017</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">2</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2017/05/">
                <span class="level-start">
                    <span class="level-item">五月 2017</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">4</span>
                </span>
            </a>
        </li>
        
        </ul>
        </div>
    </div>
</div>
        
        </div>
    
</div>

                




<div class="column is-4-tablet is-4-desktop is-2-widescreen is-hidden-touch is-hidden-desktop-only has-order-3 column-right ">
    
        
<div class="card widget">
    <div class="card-content">
        <div class="menu">
            <h3 class="menu-label">
                分类
            </h3>
            <ul class="menu-list">
            <li>
        <a class="level is-marginless" href="/hexblog/categories/DB/">
            <span class="level-start">
                <span class="level-item">DB</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">41</span>
            </span>
        </a><ul><li>
        <a class="level is-marginless" href="/hexblog/categories/DB/InfluxDB/">
            <span class="level-start">
                <span class="level-item">InfluxDB</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">16</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/DB/Mongo/">
            <span class="level-start">
                <span class="level-item">Mongo</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">11</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/DB/Mysql/">
            <span class="level-start">
                <span class="level-item">Mysql</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">13</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/DB/分库分表/">
            <span class="level-start">
                <span class="level-item">分库分表</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li></ul></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Java/">
            <span class="level-start">
                <span class="level-item">Java</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">52</span>
            </span>
        </a><ul><li>
        <a class="level is-marginless" href="/hexblog/categories/Java/Agent/">
            <span class="level-start">
                <span class="level-item">Agent</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">2</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Java/Android/">
            <span class="level-start">
                <span class="level-item">Android</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Java/Bugfix/">
            <span class="level-start">
                <span class="level-item">Bugfix</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">3</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Java/IO/">
            <span class="level-start">
                <span class="level-item">IO</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">3</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Java/JDK/">
            <span class="level-start">
                <span class="level-item">JDK</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">22</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Java/JVM/">
            <span class="level-start">
                <span class="level-item">JVM</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">9</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Java/JavaWeb/">
            <span class="level-start">
                <span class="level-item">JavaWeb</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">2</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Java/其他/">
            <span class="level-start">
                <span class="level-item">其他</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">4</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Java/问题记录/">
            <span class="level-start">
                <span class="level-item">问题记录</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">6</span>
            </span>
        </a></li></ul></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Python/">
            <span class="level-start">
                <span class="level-item">Python</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">33</span>
            </span>
        </a><ul><li>
        <a class="level is-marginless" href="/hexblog/categories/Python/Mongo/">
            <span class="level-start">
                <span class="level-item">Mongo</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Python/MySql/">
            <span class="level-start">
                <span class="level-item">MySql</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">2</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Python/教程/">
            <span class="level-start">
                <span class="level-item">教程</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">25</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Python/采坑记录/">
            <span class="level-start">
                <span class="level-item">采坑记录</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">2</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Python/项目/">
            <span class="level-start">
                <span class="level-item">项目</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li></ul></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Quick系列/">
            <span class="level-start">
                <span class="level-item">Quick系列</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">30</span>
            </span>
        </a><ul><li>
        <a class="level is-marginless" href="/hexblog/categories/Quick系列/QuickAlarm/">
            <span class="level-start">
                <span class="level-item">QuickAlarm</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">8</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Quick系列/QuickCrawler/">
            <span class="level-start">
                <span class="level-item">QuickCrawler</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">5</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Quick系列/QuickFix/">
            <span class="level-start">
                <span class="level-item">QuickFix</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">6</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Quick系列/QuickMedia/">
            <span class="level-start">
                <span class="level-item">QuickMedia</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">2</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Quick系列/QuickSpi/">
            <span class="level-start">
                <span class="level-item">QuickSpi</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">4</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Quick系列/QuickTask/">
            <span class="level-start">
                <span class="level-item">QuickTask</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">5</span>
            </span>
        </a></li></ul></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Shell/">
            <span class="level-start">
                <span class="level-item">Shell</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">39</span>
            </span>
        </a><ul><li>
        <a class="level is-marginless" href="/hexblog/categories/Shell/CMD/">
            <span class="level-start">
                <span class="level-item">CMD</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">18</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Shell/Docker/">
            <span class="level-start">
                <span class="level-item">Docker</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">4</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Shell/Git/">
            <span class="level-start">
                <span class="level-item">Git</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">3</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Shell/Maven/">
            <span class="level-start">
                <span class="level-item">Maven</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Shell/Ngins/">
            <span class="level-start">
                <span class="level-item">Ngins</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Shell/Nginx/">
            <span class="level-start">
                <span class="level-item">Nginx</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">2</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Shell/环境搭建/">
            <span class="level-start">
                <span class="level-item">环境搭建</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">9</span>
            </span>
        </a></li></ul></li><li>
        <a class="level is-marginless" href="/hexblog/categories/前端/">
            <span class="level-start">
                <span class="level-item">前端</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">8</span>
            </span>
        </a><ul><li>
        <a class="level is-marginless" href="/hexblog/categories/前端/Chrome/">
            <span class="level-start">
                <span class="level-item">Chrome</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/前端/Css/">
            <span class="level-start">
                <span class="level-item">Css</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">3</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/前端/Jquery/">
            <span class="level-start">
                <span class="level-item">Jquery</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/前端/ReactJS/">
            <span class="level-start">
                <span class="level-item">ReactJS</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">2</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/前端/Vue/">
            <span class="level-start">
                <span class="level-item">Vue</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li></ul></li><li>
        <a class="level is-marginless" href="/hexblog/categories/工具/">
            <span class="level-start">
                <span class="level-item">工具</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">9</span>
            </span>
        </a><ul><li>
        <a class="level is-marginless" href="/hexblog/categories/工具/工具类/">
            <span class="level-start">
                <span class="level-item">工具类</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">6</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/工具/插件系列/">
            <span class="level-start">
                <span class="level-item">插件系列</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">3</span>
            </span>
        </a></li></ul></li><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/">
            <span class="level-start">
                <span class="level-item">开源</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">46</span>
            </span>
        </a><ul><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/Guava/">
            <span class="level-start">
                <span class="level-item">Guava</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">2</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/Hexo/">
            <span class="level-start">
                <span class="level-item">Hexo</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/Hystrix/">
            <span class="level-start">
                <span class="level-item">Hystrix</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/Mybatis/">
            <span class="level-start">
                <span class="level-item">Mybatis</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">2</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/OGNL/">
            <span class="level-start">
                <span class="level-item">OGNL</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">3</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/RabbitMQ/">
            <span class="level-start">
                <span class="level-item">RabbitMQ</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">8</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/Redis/">
            <span class="level-start">
                <span class="level-item">Redis</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">3</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/Solr/">
            <span class="level-start">
                <span class="level-item">Solr</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/Spring/">
            <span class="level-start">
                <span class="level-item">Spring</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">24</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/Yaml/">
            <span class="level-start">
                <span class="level-item">Yaml</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li></ul></li><li>
        <a class="level is-marginless" href="/hexblog/categories/火花/">
            <span class="level-start">
                <span class="level-item">火花</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">4</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/随笔/">
            <span class="level-start">
                <span class="level-item">随笔</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">7</span>
            </span>
        </a><ul><li>
        <a class="level is-marginless" href="/hexblog/categories/随笔/idea/">
            <span class="level-start">
                <span class="level-item">idea</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/随笔/吐槽/">
            <span class="level-start">
                <span class="level-item">吐槽</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li></ul></li>
            </ul>
        </div>
    </div>
</div>
    
        <div class="card widget">
    <div class="card-content">
        <div class="menu">
        <h3 class="menu-label">
            归档
        </h3>
        <ul class="menu-list">
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2020/03/">
                <span class="level-start">
                    <span class="level-item">三月 2020</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">14</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2020/02/">
                <span class="level-start">
                    <span class="level-item">二月 2020</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">1</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2020/01/">
                <span class="level-start">
                    <span class="level-item">一月 2020</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">4</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/12/">
                <span class="level-start">
                    <span class="level-item">十二月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">5</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/11/">
                <span class="level-start">
                    <span class="level-item">十一月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">6</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/10/">
                <span class="level-start">
                    <span class="level-item">十月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">2</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/09/">
                <span class="level-start">
                    <span class="level-item">九月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">4</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/08/">
                <span class="level-start">
                    <span class="level-item">八月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">5</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/07/">
                <span class="level-start">
                    <span class="level-item">七月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">11</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/06/">
                <span class="level-start">
                    <span class="level-item">六月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">7</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/05/">
                <span class="level-start">
                    <span class="level-item">五月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">12</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/04/">
                <span class="level-start">
                    <span class="level-item">四月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">7</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/03/">
                <span class="level-start">
                    <span class="level-item">三月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">7</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/02/">
                <span class="level-start">
                    <span class="level-item">二月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">3</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/01/">
                <span class="level-start">
                    <span class="level-item">一月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">14</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/12/">
                <span class="level-start">
                    <span class="level-item">十二月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">8</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/11/">
                <span class="level-start">
                    <span class="level-item">十一月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">10</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/10/">
                <span class="level-start">
                    <span class="level-item">十月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">1</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/09/">
                <span class="level-start">
                    <span class="level-item">九月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">13</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/08/">
                <span class="level-start">
                    <span class="level-item">八月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">11</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/07/">
                <span class="level-start">
                    <span class="level-item">七月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">23</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/06/">
                <span class="level-start">
                    <span class="level-item">六月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">22</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/05/">
                <span class="level-start">
                    <span class="level-item">五月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">11</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/04/">
                <span class="level-start">
                    <span class="level-item">四月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">11</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/03/">
                <span class="level-start">
                    <span class="level-item">三月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">16</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/02/">
                <span class="level-start">
                    <span class="level-item">二月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">10</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/01/">
                <span class="level-start">
                    <span class="level-item">一月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">13</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2017/12/">
                <span class="level-start">
                    <span class="level-item">十二月 2017</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">6</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2017/09/">
                <span class="level-start">
                    <span class="level-item">九月 2017</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">1</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2017/08/">
                <span class="level-start">
                    <span class="level-item">八月 2017</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">3</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2017/07/">
                <span class="level-start">
                    <span class="level-item">七月 2017</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">2</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2017/06/">
                <span class="level-start">
                    <span class="level-item">六月 2017</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">2</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2017/05/">
                <span class="level-start">
                    <span class="level-item">五月 2017</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">4</span>
                </span>
            </a>
        </li>
        
        </ul>
        </div>
    </div>
</div>
    
    
</div>

            </div>
        </div>
    </section>
    <footer class="footer">
    <div class="container">
        <div class="level">
            <div class="level-start has-text-centered-mobile">
                <a class="footer-logo is-block has-mb-6" href="/hexblog/">
                
                    <img src="/hexblog/images/avatar.jpg" alt="Java并发学习之线程池ThreadPoolExecutor的小结" height="28">
                
                </a>
                <p class="is-size-7">
                &copy; 2020 YiHui&nbsp;
                Powered by <a href="https://hexo.io/" target="_blank">Hexo</a> & <a
                        href="https://github.com/ppoffice/hexo-theme-icarus" target="_blank">Icarus</a>
                
                </p>
            </div>
            <div class="level-end">
            
                <div class="field has-addons is-flex-center-mobile has-mt-5-mobile is-flex-wrap is-flex-middle">
                
                
                <p class="control">
                    <a class="button is-white is-large" target="_blank" title="Download on GitHub" href="https://github.com/liuyueyi">
                        
                        <i class="fab fa-github"></i>
                        
                    </a>
                </p>
                
                <p class="control">
                    <a class="button is-white is-large" target="_blank" title="Chart in Weibo" href="https://weibo.com/p/1005052169825577/home">
                        
                        <i class="fab fa-weibo"></i>
                        
                    </a>
                </p>
                
                <p class="control">
                    <a class="button is-white is-large" target="_blank" title="Frends with me" href="https://s10.mogucdn.com/mlcdn/c45406/171229_1cgld3igbelkbc70cd8af1j3809kb_150x150.jpg">
                        
                        <i class="fab fa-weixin"></i>
                        
                    </a>
                </p>
                
                </div>
            
            </div>
        </div>
    </div>
    <hr/>
    <div id="foot-pannel">
        <div class="outer">
            <div class="foot-column">
                <!--关注我们-->
                <div class="widget-wrap widget-list">
                    <h3 class="widget-title">更多平台</h3>
                    <div class="widget">
                        <ul>
                            <li>
                                <a href="//blog.hhui.top/">一灰灰Blog</a>
                            </li>
                        
                            <li>
                                <a href="//juejin.im/user/5a2a4b095188252ae93adbbf/posts">掘金</a>
                            </li>
                        
                            <li>
                                <a href="//my.oschina.net/u/566591">开源中国</a>
                            </li>
                        
                            <li>
                                <a href="//blog.csdn.net/liuyueyi25">CSDN</a>
                            </li>
                        
                            <li>
                                <a href="//www.jianshu.com/u/5902ab08e670">简书</a>
                            </li>
                        
                            <li>
                                <a href="//cloud.tencent.com/developer/column/1847">云+</a>
                            </li>
                        
                            <li>
                                <a href="//www.toutiao.com/c/user/69862071663/#mid=1579653107239950">头条</a>
                            </li>
                        
                            <li>
                                <a href="//github.com/liuyueyi">GitHub</a>
                            </li>
                        
                            <li>
                                <a href="//gitee.com/liuyueyi">Gitee</a>
                            </li>
                            
                        </ul>
                    </div>
                </div>
            </div>
            <div class="foot-column">
                <!--联系合作-->
                <div class="widget-wrap widget-list">
                    <h3 class="widget-title">一灰灰Blog</h3>
                    <div class="widget">
                        <ul>
                            
                                <li>
                                    <a href="#">QQ : 3302797840</a>
                                </li>
                            
                                <li>
                                    <a href="#">微信 : liuyueyi25</a>
                                </li>
                            
                                <li>
                                    <a href="#">邮箱 : bangzewu@126.com</a>
                                </li>
                            
                                <li>
                                    <a href="#">微博 : 一灰灰blog</a>
                                </li>
                            
                        </ul>
                    </div>
                </div>
                <div class="widget-wrap widget-list">
                    <h3 class="widget-title">友情链接</h3>
                    <div class="widget">
                        <ul>
                            
                                <span class="label">
                                    <a target="_blank" href="//zweb.hhui.top">zweb多媒体工具页</a>
                                </span>
                            
                                <span class="label">
                                    <a target="_blank" href="//mweb.hhui.top">mweb古诗选</a>
                                </span>
                            
                        </ul>
                    </div>
                </div>
            </div>
            <div class="foot-column">
                <!--友情链接-->
                <div class="widget-wrap widget-list">
                    <h3 class="widget-title">知识星球</h3>
                    <div class="widget">
                        <img style="width: 200px;" src="/hexblog/imgs/info/xingqiu.png">
                    </div>
                </div>
                
            </div>
            <div class="foot-column">
                <div class="widget-wrap widget-list">
                    <h3 class="widget-title">公众号</h3>
                    <div class="widget">
                        <img style="width: 200px;" src="/hexblog/imgs/info/wx.jpg">
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div style="padding-top:20em">
        <hr/>
        <div id="foot-info">
            <span style="margin:4px;font-size:1em">
                &copy; 2020 <a target='_blank' href='https://github.com/liuyueyi'>一灰灰Blog</a> 版权所有 | <a href="http://www.beian.miit.gov.cn" target="_blank">鄂ICP备18017282号</a>
            </span>
            <br/>
            <span style="margin:4px;font-size:1em">
                <script type="text/javascript">document.write(unescape("%3Cspan id='cnzz_stat_icon_1278691600'%3E%3C/span%3E%3Cscript src='https://s9.cnzz.com/z_stat.php%3Fid%3D1278691600%26online%3D1%26show%3Dline' type='text/javascript'%3E%3C/script%3E"));</script>
            </span>
            <span style="margin:1em;font-size:1.4em">
                <label id="self_count_cnt"><br>本站总访量: <span class="visit_cnt">69330</span> | 总访问人次: <span class="visit_cnt">11586</span> | 恭喜您为第 <span class="visit_cnt">10840</span> 访问者</label>
            </span>
            <script src="/hexblog/js/count.js"></script>
        </div>
    </div>
</footer>
    <script src="https://cdn.jsdelivr.net/npm/jquery@3.3.1/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/moment@2.22.2/min/moment-with-locales.min.js"></script>
<script>moment.locale("zh-CN");</script>


    
    
    
    <script src="/hexblog/js/animation.js"></script>
    

    
    
    
    <script src="https://cdn.jsdelivr.net/npm/lightgallery@1.6.8/dist/js/lightgallery.min.js" defer></script>
    <script src="https://cdn.jsdelivr.net/npm/justifiedGallery@3.7.0/dist/js/jquery.justifiedGallery.min.js" defer></script>
    <script src="/hexblog/js/gallery.js" defer></script>
    

    
    

<div id="outdated">
    <h6>Your browser is out-of-date!</h6>
    <p>Update your browser to view this website correctly. <a id="btnUpdateBrowser" href="http://outdatedbrowser.com/">Update
            my browser now </a></p>
    <p class="last"><a href="#" id="btnCloseUpdateBrowser" title="Close">&times;</a></p>
</div>
<script src="https://cdn.jsdelivr.net/npm/outdatedbrowser@1.1.5/outdatedbrowser/outdatedbrowser.min.js" defer></script>
<script>
    document.addEventListener("DOMContentLoaded", function () {
        outdatedBrowser({
            bgColor: '#f25648',
            color: '#ffffff',
            lowerThan: 'flex'
        });
    });
</script>


    
    
<script src="https://cdn.jsdelivr.net/npm/mathjax@2.7.5/unpacked/MathJax.js?config=TeX-MML-AM_CHTML" defer></script>
<script>
document.addEventListener('DOMContentLoaded', function () {
    MathJax.Hub.Config({
        'HTML-CSS': {
            matchFontHeight: false
        },
        SVG: {
            matchFontHeight: false
        },
        CommonHTML: {
            matchFontHeight: false
        },
        tex2jax: {
            inlineMath: [
                ['$','$'],
                ['\\(','\\)']
            ]
        }
    });
});
</script>

    
    

<a id="back-to-top" title="回到顶端" href="javascript:;">
    <i class="fas fa-chevron-up"></i>
</a>
<script src="/hexblog/js/back-to-top.js" defer></script>


    
    

    
    
    
    

    
    
    
    
    
    <script src="https://cdn.jsdelivr.net/npm/clipboard@2.0.4/dist/clipboard.min.js" defer></script>
    <script src="/hexblog/js/clipboard.js" defer></script>
    

    
    
    


<script src="/hexblog/js/main.js" defer></script>

    
    <div class="searchbox ins-search">
    <div class="searchbox-container ins-search-container">
        <div class="searchbox-input-wrapper">
            <input type="text" class="searchbox-input ins-search-input" placeholder="想要查找什么..." />
            <span class="searchbox-close ins-close ins-selectable"><i class="fa fa-times-circle"></i></span>
        </div>
        <div class="searchbox-result-wrapper ins-section-wrapper">
            <div class="ins-section-container"></div>
        </div>
    </div>
</div>
<script>
    (function (window) {
        var INSIGHT_CONFIG = {
            TRANSLATION: {
                POSTS: '文章',
                PAGES: '页面',
                CATEGORIES: '分类',
                TAGS: '标签',
                UNTITLED: '(无标题)',
            },
            CONTENT_URL: '/hexblog/content.json',
        };
        window.INSIGHT_CONFIG = INSIGHT_CONFIG;
    })(window);
</script>
<script src="/hexblog/js/insight.js" defer></script>
<link rel="stylesheet" href="/hexblog/css/search.css">
<link rel="stylesheet" href="/hexblog/css/insight.css">
    
</body>
</html>